MySQL Передача имени таблицы для выбора курсора - PullRequest
3 голосов
/ 14 октября 2010

Я хочу, чтобы процедура приняла параметр answertable и partid в операторе выбора, но когда я вызываю его, он не заменяет параметр answertable значением

звонок call updateTotalScores('quiz_participation', 'quiz_answer', 1)

возвращает ошибку: 1146 - Table 'quizdb.answertable' doesn't exist

передача идентификатора работает, но передача имени таблицы - нет так как мне передать имя таблицы в select в

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 Ответ

2 голосов
/ 14 октября 2010

Я считаю, что вы не можете сделать это таким образом.

Для этого вам следует использовать динамический 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;

Примечание: пожалуйста, проверьте синтаксис.Я не могу проверить это, чтобы точно проверить, но я надеюсь, что вы поняли идею.

...