MySQL抱怨多行

时间:2016-07-07 22:45:35

标签: mysql

我在mysql存储过程中有以下逻辑:

SET @UserId = (
Select userid
FROM tickets
where ticketid = ticketID
);

它给了我一个错误:

  

子查询返回超过1行

我删除了它周围的集合并运行了查询:

Select userid
FROM tickets
where ticketid = ticketID;

我找回1条记录,为什么抱怨我有超过1行? ticketid也是该表的主键!

2 个答案:

答案 0 :(得分:2)

看起来像WHERE子句中的谓词

 ticketid = ticketID 
对于ticketid的所有非空值,

将评估为TRUE。

基本上等同于指定

 ticketid IS NOT NULL

如果ticketid是PRIMARY KEY,那么表中的每一行都会满足该条件。

我只是在这里猜测。我怀疑你已经声明了一个名为ticketID的变量,并期望MySQL区分ticketid作为列的引用,ticketID是对变量的引用。但这不会发生。如果存在名为ticketID的过程变量(在SQL语句的范围内声明),则MySQL会引用ticketid作为对变量的引用。因此,如果ticketid变量具有非空值,则将再次返回表中的每一行。

从MySQL参考手册:

  

局部变量的名称不应与表列相同。如果SQL语句(例如SELECT ... INTO语句)包含对列的引用和声明的具有相同名称的局部变量,则MySQL当前会将对该名称的引用解释为变量名称。

参考:http://dev.mysql.com/doc/refman/5.7/en/local-variable-scope.html

如果这是问题(再次,我只是在猜测),解决方法是限定对带有表名或表别名的列的引用。

许多开发人员还使用前缀或其他约定命名变量,这使读者可以通过减少歧义来更容易地区分变量名和列名。

例如:

  DECLARE lv_ticketid INT; 

  SET @UserId = ( SELECT t.userid FROM tickets t WHERE t.ticketid = lv_ticketid );

我们知道只返回一行,我们也可以在查询中添加一个LIMIT 1,具体取决于我们是否希望在返回多行时抛出错误。

  SET @UserId = ( SELECT t.userid
                   FROM tickets t
                  WHERE t.ticketid = lv_ticketid 
                  ORDER BY t.userid ASC
                  LIMIT 1 
                );

答案 1 :(得分:0)

对于列名和关键字,MySQL不区分大小写。当你说where ticketid = ticketID它认为你只是说列ticketid的值与它本身相同时,它总是正确的。尝试将变量更改为其他内容。