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

Mr.*_*Boy 24 mysql stored-procedures

我想要一个有效的MySQL存储过程:

foreach id in (SELECT id FROM objects WHERE ... ) CALL testProc(id)

我想我只是希望MySQL回答这个问题,但我不太了解游标:如何为查询返回的每一行执行一次存储过程?

egg*_*yal 42

诸如"循环"(for-each,while等)和"分支"(if-else,call等)之类的概念是程序性的,并且在SQL等声明性语言中不存在.通常,人们可以用声明的方式表达一个人想要的结果,这将是解决这个问题的正确方法.

例如,如果testProc要调用的过程使用给定id的查找键作为另一个表的查找键,那么您可以(而且应该)简单地JOIN将您的表放在一起 - 例如:

SELECT ...
FROM   objects JOIN other USING (id)
WHERE  ...
Run Code Online (Sandbox Code Playgroud)

只有在非常罕见的情况下,如果您的问题无法以声明方式表达,那么您应该在程序上解决问题.存储过程是在MySQL中执行过程代码的唯一方法.因此,您需要修改现有的sproc,以便它在循环中执行其当前逻辑,或者创建一个从循环内调用现有sproc的新sproc:

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
Run Code Online (Sandbox Code Playgroud)

  • 这种手动设置变量来终止“循环”的模式,这是正常的方式吗?看起来好笨重啊! (2认同)