簡體   English   中英

MySQL存儲過程選擇語句發現不正確的結果

[英]MySQL Stored Procedure select statement finding inaccurate result

我有一個存儲過程,應該簡單地檢查電子郵件是否已經存在,並根據是否找到ID返回布爾值TRUE或FALSE

該表如下所示: 在此處輸入圖片說明

結果是這樣的:

在此處輸入圖片說明

這是完全錯誤的

步驟如下:

CREATE PROCEDURE `EmailExists` (email VARCHAR(255), OUT output BOOL)
email_exists_proc:BEGIN
    DECLARE existing_id CHAR(36);
    DECLARE existing_email2 varchar(255);
    DECLARE found_name varchar(255);

    SELECT 
        `id`, `email`, `display_name` INTO existing_id, existing_email2, found_name
    FROM `account`
    WHERE `email` = email
    LIMIT 1;

    SELECT "EMail Exists", existing_email2, " == ", email, " ? ", existing_id, "name: ", found_name, existing_id IS NOT NULL;

    SELECT existing_id IS NOT NULL INTO output;
END$$

這是非常基本的查詢,這是調用:

CALL EmailExists("something@something.com", @exists);
SELECT @exists; # this returns 1 right now, it should be 0, but it's "finding" the provided email, somehow. 

我想念的是什么,我在這里做錯了什么? 為什么existing_email2最終會鏡像email 該值在表中不存在。

限定查詢中對列的引用,因此,用於引用列的標識符實際上是在引用列,而不是過程變量。

反引號用於轉義標識符。 反引號不標識哪些標識符引用列以及哪些引用過程變量。

將表別名a分配給account表,並用a.限定所有列引用a.

  SELECT a.`id`
       , a.`email`
       , a.`display_name`
    FROM `account` a
   WHERE a.`email` = email
   LIMIT 1
    INTO existing_id
       , existing_email2
       , found_name
  ;

最佳實踐是將名稱用於列名稱不同的過程變量。

我個人的喜好是對過程值使用其他名稱

... PROCEDURE `EmailExists` (as_email VARCHAR(255), ...
                             ^^

然后這個

   WHERE a.`email` = as_email

對於人類讀者而言,它的含糊性較小。

然后,要獲得原始代碼中的行為,我們將編寫為:

   WHERE as_email = as_email

這使為什么accounts每一行都滿足為as_email提供的任何非NULL值滿足該條件的原因變得更加明顯。


參考: https : //dev.mysql.com/doc/refman/5.7/en/stored-program-restrictions.html

存儲例程中的名稱沖突

相同的標識符可能用於例程參數,局部變量和表列。 同樣,可以在嵌套塊中使用相同的局部變量名稱。 例如:

在這種情況下,標識符不明確,並且適​​用以下優先級規則:

  • 局部變量優先於常規參數或表列。

  • 例程參數優先於表列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM