我有2个表:问题和测验。
测验是一系列问题。
测验表如下所示:
1 | 1,2,3,4,5
2 | 6,7,8,9
问题表具有主键ID(整数),问题和状态字段
我想写一个程序来更新问题表中所有问题的状态。
以下查询适用于SQL控制台
UPDATE questions SET ActiveStatus = 'X'
WHERE FIND_IN_SET(ID, (SELECT QuestionIds from quiz where QuizId = 2)) > 0
此处更新了4行。
但是,当我在存储过程中放入相同的查询并使用参数执行它时,它不起作用。
存储过程代码:
CREATE DEFINER=`root`@`localhost`
PROCEDURE `update_quiz_status`(IN `QuizId` INT, IN `Status` VARCHAR(1))
MODIFIES SQL DATA
SQL SECURITY INVOKER
UPDATE questions SET ActiveStatus = Status
WHERE FIND_IN_SET(ID, (SELECT QuestionIds from quiz where QuizId = QuizId)) > 0
过程没有语法错误。
当我从SQL控制台调用该过程时,出现错误:
call update_quiz_status(2,'X');
错误:#1242 - 子查询返回超过1行
我不知道为什么查询在SQL控制台中有效但在存储过程中无效!
我还有其他办法吗?即通过SQL过程更新给定测验的问题状态。
答案 0 :(得分:3)
你的问题在这里
SELECT QuestionIds from quiz where QuizId = QuizId
在你看来,第二个QuizId
指的是传递的参数。但是,解析器将其视为QuizId
表中的quiz
,因此返回该表中的所有行。
更改参数的名称,你应该没问题。
答案 1 :(得分:1)
你有一个非常非常糟糕的数据结构。你应该有一个表QuizQuestions
,每个问题和测验有一行。
那说,问题就在这一行:
WHERE FIND_IN_SET(ID, (SELECT QuestionIds from quiz where QuizId = QuizId)) > 0
QuizId
在两种情况下都是相同的。您应该将变量重命名为v_QuizId
,然后使用where
子句的别名:
WHERE FIND_IN_SET(ID, (SELECT QuestionIds from quiz q where q.QuizId = v_QuizId)) > 0