MySQL Pass表名称到光标选择

时间:2010-10-14 08:15:45

标签: mysql sql stored-procedures mysql-error-1146

我希望程序在select语句中使用参数 answertable partid , 但是当我调用它时,它不会用值

替换参数answertable

致电call updateTotalScores('quiz_participation', 'quiz_answer', 1)

返回错误:1146 - Table 'quizdb.answertable' doesn't exist

传递id有效,但传递表名却不行 那么如何将表名传递给

中的选择
DECLARE cur1 CURSOR FOR SELECT SUM(`score`), SUM(`maxscore`) FROM answertable WHERE `idParticipation`=partid;

整个程序:

DELIMITER $$
CREATE PROCEDURE updateTotalScores(IN participationtable CHAR(64), IN answertable CHAR(64), IN partid INT)
BEGIN
 DECLARE done INTEGER DEFAULT 0;
 DECLARE sscore INTEGER DEFAULT 0;
 DECLARE smaxscore INTEGER DEFAULT 0;
 DECLARE cur1 CURSOR FOR SELECT SUM(`score`), SUM(`maxscore`) FROM answertable WHERE `idParticipation`=partid;
 DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;

 OPEN cur1;
 REPEAT
  FETCH cur1 INTO sscore, smaxscore;
  UNTIL done = 1
 END REPEAT;
 CLOSE cur1;

 UPDATE participationtable SET `score`=sscore, `maxscore`=smaxscore WHERE `idParticipation`=partid;
END $$
DELIMITER ;

为了完整性

表名不能传递给MySql游标,至少还没有

http://forge.mysql.com/worklog/task.php?id=3433

下面的答案(有点纠正)

DELIMITER $$

CREATE PROCEDURE updateTotalScores(IN participation_table VARCHAR(45), IN answer_table VARCHAR(45), IN part_id INT)
BEGIN
    SET @stmt_text=CONCAT("SELECT @score := SUM(`score`), @maxscore := SUM(`maxscore`) FROM ",
                         answer_table, " WHERE `idParticipation`=",  part_id);
    PREPARE stmt FROM @stmt_text;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;

    SET @stmt_text=CONCAT("UPDATE ", participation_table, 
                        " SET `score`=?, `maxscore`=? WHERE `idParticipation`=", part_id);
    PREPARE stmt FROM @stmt_text;
    EXECUTE stmt USING @score, @maxscore;
    DEALLOCATE PREPARE stmt;
END $$

1 个答案:

答案 0 :(得分:2)

我相信你不能这样做。

为了实现这一点,您应该使用动态SQL。

请注意,您也无法使用动态SQL打开游标。但在你的情况下,似乎不需要游标。

如果我正确理解你的代码,你可以使用用户变量,并且可能使用2个动态准备的语句来实现你想要做的事情。

  SET @stmt_text=CONCAT("SELECT @score = SUM(`score`), @maxscore=SUM(`maxscore`) FROM ",                
                         answertable, "WHERE `idParticipation`= ",  partid);
  PREPARE stmt FROM @stmt_text;
  EXECUTE stmt USING @a;

然后使用以下语句更新值

  SET @stmt_text=CONCAT("UPDATE", participationtable, " SET `score`=@score,  
                      `maxscore`=@maxscore WHERE `idParticipation`=", partid);

  PREPARE stmt FROM @stmt_text;
  EXECUTE stmt USING @a;

  DEALLOCATE PREPARE stmt;

注意:请检查语法。我无法测试它以确切地验证它,但我希望你能得到这个想法。