为MySQL中查询返回的每一行调用一个存储过程

为MySQL中查询返回的每一行调用一个存储过程,mysql,stored-procedures,Mysql,Stored Procedures,我想要一个MySQL存储过程,它可以有效地执行以下操作: 从对象中选择id中的foreach id,其中。。。调用testProcid 我想我只是想用MySQL来回答这个问题,但我不太理解游标:诸如每个的“循环”、while等和“分支”if else、call等概念都是过程性的,在SQL等声明性语言中不存在。通常,人们可以用声明的方式表达自己想要的结果,这是解决这个问题的正确方法 例如,如果要调用的testProc过程使用给定id作为另一个表的查找键,那么您可以也应该简单地将表连接在一起,例如:

我想要一个MySQL存储过程,它可以有效地执行以下操作:

从对象中选择id中的foreach id,其中。。。调用testProcid


我想我只是想用MySQL来回答这个问题,但我不太理解游标:

诸如每个的“循环”、while等和“分支”if else、call等概念都是过程性的,在SQL等声明性语言中不存在。通常,人们可以用声明的方式表达自己想要的结果,这是解决这个问题的正确方法

例如,如果要调用的testProc过程使用给定id作为另一个表的查找键,那么您可以也应该简单地将表连接在一起,例如:

SELECT ...
FROM   objects JOIN other USING (id)
WHERE  ...
只有在极为罕见的情况下,当你的问题无法用声明的方式表达时,你才应该采取程序化的方式来解决它。存储过程是MySQL中执行过程代码的唯一方法。因此,您需要修改现有存储过程,使其在循环中执行当前逻辑,或者创建一个新存储过程,从循环中调用现有存储过程:

CREATE PROCEDURE foo() BEGIN
  DECLARE done BOOLEAN DEFAULT FALSE;
  DECLARE _id BIGINT UNSIGNED;
  DECLARE cur CURSOR FOR SELECT id FROM objects WHERE ...;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;

  OPEN cur;

  testLoop: LOOP
    FETCH cur INTO _id;
    IF done THEN
      LEAVE testLoop;
    END IF;
    CALL testProc(_id);
  END LOOP testLoop;

  CLOSE cur;
END

这种手动设置变量以终止“循环”的模式,这是正常的方式吗?它看起来太笨重了@约翰:是的。虽然为表中的每条记录调用过程的模式不太正常,但至少可以在testProc内的游标上迭代,但即使这样也可能是不必要的:testProc做什么?这是一个游戏,当游戏结束时,它必须更新与每个玩家相关的几个表。。。因此,在您的示例中,foo迭代链接到单个游戏的每个玩家,testProc为单个玩家执行一系列操作。DB中的应用程序逻辑比其他任何东西都重要。记住,如果你有更多选择,例如,在你需要创建更多的_价格之前和之后的产品价格,_newPrice,然后才能获取_价格和_newPrice。非常感谢这篇简单的文章。语法错误:DECLARE done BOOLEAN DEFAULT FALSE后缺少半列;