27

効果的に実行する MySQL ストアド プロシージャが必要です。

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

この質問に対する MySQL の回答が欲しいだけだと思いますが、カーソルがよくわかりません。クエリによって返される行ごとにストアド プロシージャを 1 回実行するにはどうすればよいですか?

4

1 に答える 1

44

「ループ」 (for-each、while など) や「分岐」 (if-else、call など) などの概念は手続き型であり、SQL のような宣言型言語には存在しません。通常、目的の結果を宣言的な方法で表現できます。これは、この問題を解決する正しい方法です。

たとえば、testProc呼び出されるプロシージャが、指定された を別のテーブルへのルックアップ キーとして使用する場合、代わりに単純にテーブルをまとめるidこともできます (またそうする必要があります) 。たとえば、次のようになります。JOIN

SELECT ...
FROM   objects JOIN other USING (id)
WHERE  ...

問題を宣言的に表現できないという非常にまれな状況でのみ、代わりに手続き的に解決する必要があります。ストアドプロシージャは、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
于 2013-01-14T22:32:40.007 に答える