-2

我有 2 张桌子:问题和测验。

测验是问题的集合。

测验表如下所示:

测验ID | QuestionIds (NVARCHAR50)

  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 过程更新给定测验的问题状态。

4

2 回答 2

3

你的问题在这里

SELECT QuestionIds from quiz where QuizId = QuizId

在您看来,第二个QuizId是指传递的参数。但是,解析器将其视为表QuizId中的 ,因此返回该quiz表中的所有行。

更改参数的名称,您应该没问题。

于 2013-08-19T20:10:13.450 回答
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
于 2013-08-19T20:10:21.713 回答