72

やや単純な選択クエリを実行し、追加のクエリ、データ変換、またはデータを完全に破棄するかどうかを決定するために結果をループするストアド プロシージャを MySQL で作成しようとしています。効果的に、私はこれを実装したいと思います:

$result = mysql_query("SELECT something FROM somewhere WHERE some stuff");
while ($row = mysql_fetch_assoc($result)) {
    // check values of certain fields, decide to perform more queries, or not
    // tack it all into the returning result set
}

ただ、MySQLだけにしたいので、プロシージャとして呼び出すことができます。トリガーにはFOR EACH ROW ...構文があることは知っていますが、構文以外で使用するためのこのようなものについての言及は見つかりませんCREATE TRIGGER ...。MySQL のループ メカニズムのいくつかを読みましたが、今のところ想像できるのは、次のようなものを実装することだけです。

SET @S = 1;
LOOP
    SELECT * FROM somewhere WHERE some_conditions LIMIT @S, 1
    -- IF NO RESULTS THEN
    LEAVE
    -- DO SOMETHING
    SET @S = @S + 1;
END LOOP

これでも頭がぼやけていますが。

参考までに、必ずしも関係があるとは思いませんが、最初のクエリは 4 つのテーブルを結合して階層的なアクセス許可のモデルを形成し、特定のアクセス許可がチェーンのどの程度上にあるかに基づいて、次の追加情報を取得します。その権限を継承する子。

4

2 に答える 2

100

このようなものでうまくいくはずです(ただし、詳細についてはスニペットの後に読んでください)

CREATE PROCEDURE GetFilteredData()
BEGIN
  DECLARE bDone INT;

  DECLARE var1 CHAR(16);    -- or approriate type
  DECLARE Var2 INT;
  DECLARE Var3 VARCHAR(50);

  DECLARE curs CURSOR FOR  SELECT something FROM somewhere WHERE some stuff;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET bDone = 1;

  DROP TEMPORARY TABLE IF EXISTS tblResults;
  CREATE TEMPORARY TABLE IF NOT EXISTS tblResults  (
    --Fld1 type,
    --Fld2 type,
    --...
  );

  OPEN curs;

  SET bDone = 0;
  REPEAT
    FETCH curs INTO var1,, b;

    IF whatever_filtering_desired
       -- here for whatever_transformation_may_be_desired
       INSERT INTO tblResults VALUES (var1, var2, var3 ...);
    END IF;
  UNTIL bDone END REPEAT;

  CLOSE curs;
  SELECT * FROM tblResults;
END

考慮すべき点がいくつかあります...

上記のスニペットに関して:

  • クエリの一部、特に検索条件をストアド プロシージャに渡して、より一般的なものにすることができます。
  • このメソッドが複数のセッションによって呼び出される場合などは、一意の一時テーブル名を作成するためにある種のセッション ID を渡したい場合があります (異なるセッションは同じ一時ファイルの名前空間を共有しないため、実際には不要な懸念です。以下の Gruber によるコメントを参照してください)。 )
  • 変数宣言、SELECT クエリなどのいくつかの部分を適切に指定する必要があります。

より一般的には、カーソルが必要になるのを避けようとしています

カーソル変数には意図的に curs[e] という名前を付けました。それらは、SQL の宣言形式で表現するのが難しい複雑なビジネス ルールを実装するのに役立ちますが、SQL の一般的な機能である手続き型 (命令型) 形式の SQL を使用することになります。表現力があり、プログラミングに関しては、多くの場合、パフォーマンスに関しては非効率的です。

おそらく、「プレーン」(宣言型) SQL クエリのコンテキストで必要な変換とフィルタリングを表現することを検討できます。

于 2009-11-16T22:31:56.643 に答える
6

カーソルを使用します。

ドキュメントを読み進めるとき、カーソルはバッファリングされたリーダーのように考えることができます。各行をドキュメントの行と考えると、次の行を読み、操作を実行してからカーソルを進めます。

于 2009-11-16T22:31:05.090 に答える