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つのテーブルを結合して階層型のアクセス許可のモデルを形成し、特定のアクセス許可のチェーンの高さに基づいて、追加の情報を取得しますその許可を継承する子。
このような何かがトリックを行う必要があります(ただし、詳細については、スニペットの後に読んでください)
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
考慮すべきいくつかのこと...
上記のスニペットについて:
より一般的には、カーソルの必要性を回避しようとする。
カーソルは祝福が混在しているため、意図的にカーソル変数curs [e]に名前を付けました。 SQLの宣言型では表現が難しいかもしれない複雑なビジネスルールを実装するのに役立ちますが、SQLの手続き型(命令型)を使用するようになります。表現力があり、プログラミングの面で、多くの場合、パフォーマンスの面で非効率的です。
「プレーン」(宣言的)SQLクエリのコンテキストで必要な変換とフィルタリングを表現することを検討できます。
カーソルを使用します。
カーソルは、ドキュメントを読むときのバッファ付きリーダーのように考えることができます。各行をドキュメント内の行と考える場合、次の行を読み、操作を実行してからカーソルを進めます。