繁体   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