我在mysql存储过程中有以下逻辑:
SET @UserId = (
Select userid
FROM tickets
where ticketid = ticketID
);
它给了我一个错误:
子查询返回超过1行
我删除了它周围的集合并运行了查询:
Select userid
FROM tickets
where ticketid = ticketID;
我找回1条记录,为什么抱怨我有超过1行? ticketid也是该表的主键!
答案 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
的值与它本身相同时,它总是正确的。尝试将变量更改为其他内容。