MySQL存储过程选择语句查找不准确的结果

时间:2018-05-16 20:33:51

标签: mysql stored-procedures

我有一个存储过程,它应该只检查电子邮件是否已经存在,并根据是否找到ID返回布尔值TRUE或FALSE

表格如下: enter image description here

结果如下:

enter image description here

这是非常不正确的

这是程序:

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?该值不存在于表中。

1 个答案:

答案 0 :(得分:1)

限定对查询中列的引用,因此用于引用列的标识实际上是引用列,而不是过程变量。

反引号用于转义标识符。反引号不能识别哪些标识符引用列以及哪些引用过程变量。

将表别名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

  

存储例程中的名称冲突

     

相同的标识符可用于例程参数,局部变量和表列。此外,可以在嵌套块中使用相同的局部变量名称。例如:

     

在这种情况下,标识符不明确,并且适​​用以下优先规则:

     
      
  • 局部变量优先于例程参数或表列。

  •   
  • 常规参数优先于表格列。

  •   
相关问题