将prepared语句与CONCAT一起使用时出现MySQL语法错误

将prepared语句与CONCAT一起使用时出现MySQL语法错误,mysql,stored-procedures,prepared-statement,variable-assignment,do-while,Mysql,Stored Procedures,Prepared Statement,Variable Assignment,Do While,我试图在存储过程中使用一个准备好的语句。我在初始集合@idToUpdateQuery中得到语法错误。我已经知道,没有使用:=的变量赋值的CONCAT可以正常工作,因为它在其他地方使用并且可以按预期工作。本质上,我只需要能够将准备好的SELECT语句的结果放入变量@resultId中。问题代码如下: SET @distinctTableXIds = (SELECT COUNT(*) FROM tempTableX); SET @i = 0; WHILE @i < @distinctTa

我试图在存储过程中使用一个准备好的语句。我在初始集合@idToUpdateQuery中得到语法错误。我已经知道,没有使用:=的变量赋值的CONCAT可以正常工作,因为它在其他地方使用并且可以按预期工作。本质上,我只需要能够将准备好的SELECT语句的结果放入变量@resultId中。问题代码如下:

SET @distinctTableXIds = (SELECT COUNT(*) FROM tempTableX);

 SET @i = 0;
 WHILE @i < @distinctTableXIds DO

    /*CONCAT IS NEEDED HERE TO PASS USER DEFINED @i*/
    SET @idToUpdateQuery = CONCAT('SELECT @result := MAX(id) 
    FROM tableY 
    WHERE tableZId = (SELECT id FROM tempTableX ORDER BY id LIMIT ', @i, ', 1)');

    PREPARE @IdToUpdateStmt FROM @IdToUpdateQuery;
    EXECUTE @IdToUpdateStmt;

    SET @resultId = SELECT @result;

    UPDATE tableY
    SET someBoolean = 1
    WHERE id = @resultId;

    SET @i = @i + 1;

 END WHILE;
不能将@sigil用作语句名。它不是一个用户变量

请参见第页的示例

除此之外,我认为你根本不需要为这项任务准备一份声明。我至少可以想出另外两种解决办法。给我几分钟,我来写一篇

一种使用光标的解决方案请参见:

另一个在一个UPDATE语句中实现所有功能的解决方案:

UPDATE tableY AS y1
INNER JOIN tempTableX AS x ON (y1.tableZId = x.id)
LEFT OUTER JOIN tableY AS y2 ON (y1.tableZId = y2.tableZId AND y1.id < y2.id)
SET y1.someBoolean = 1
WHERE y2.id IS NULL;

外部连接技巧是一种查找y1中不存在具有相同tableZId和更大id的行的方法。换句话说,它查找具有给定tableZId的每组行的最大id。

SET@idToUpdateQuery=CONCAT;中没有语法错误。。;。但是从@IdToUpdateQuery中准备@IdToUpdateStmt;看起来不对。尝试不使用@。在看了至少一个小时后,我在刷新此页面之前得出了相同的结论。谢谢。当然,我想看看另一种解决方案。我将修补更新语句注意:我还没有测试过它!请不要在真实数据上进行测试:-
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE max_id INT;
  DECLARE cur1 CURSOR FOR SELECT MAX(id) FROM tableY JOIN tempTableX ON (tableY.tableZId = temptableX.id) GROUP BY tableZId;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;

  read_loop: LOOP
    FETCH cur1 INTO max_id
    IF done THEN
      LEAVE read_loop;
    END IF;
    UPDATE tableY SET someBoolean = 1 WHERE id = max_id;
  END LOOP;

  CLOSE cur2;
END
UPDATE tableY AS y1
INNER JOIN tempTableX AS x ON (y1.tableZId = x.id)
LEFT OUTER JOIN tableY AS y2 ON (y1.tableZId = y2.tableZId AND y1.id < y2.id)
SET y1.someBoolean = 1
WHERE y2.id IS NULL;