【发布时间】:2018-08-13 01:44:44
【问题描述】:
我想要一个有效的 MySQL 存储过程:
foreach id in (SELECT id FROM objects WHERE ... ) CALL testProc(id)
我想我只是想要这个问题的 MySQL 答案,但我不太了解游标:How do I execute a stored procedure once for each row returned by query?
【问题讨论】:
我想要一个有效的 MySQL 存储过程:
foreach id in (SELECT id FROM objects WHERE ... ) CALL testProc(id)
我想我只是想要这个问题的 MySQL 答案,但我不太了解游标:How do I execute a stored procedure once for each row returned by query?
【问题讨论】:
“循环”(for-each、while 等)和“分支”(if-else、调用等)等概念是过程性的,不存在于声明性 语言,如 SQL。通常人们可以用声明的方式表达自己想要的结果,这将是解决这个问题的正确方法。
例如,如果要调用的 testProc 过程使用给定的 id 作为另一个表的查找键,那么您可以(并且应该)简单地将 JOIN 放在一起 - 例如:
SELECT ...
FROM objects JOIN other USING (id)
WHERE ...
只有在极少数情况下您的问题无法以声明方式表达时,您才应该诉诸程序解决问题。存储过程是在 MySQL 中执行过程代码的唯一方法。因此,您要么需要修改现有的 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
【讨论】:
testProc 内的游标,但即使这样也可能是不必要的:testProc 做了什么?)。
foo() 正在迭代链接到单个游戏的每个玩家,并且 @ 987654329@ 为单个玩家做了很多事情。数据库中的应用逻辑比其他任何东西都重要。
DECLARE done BOOLEAN DEFAULT FALSE; 后缺少半列