sql >> データベース >  >> RDS >> Mysql

MySQLで結果セットをループする

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

    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を渡して、一意の一時テーブル名を作成する必要があります(異なるセッションは同じ一時ファイルの名前空間を共有しないため、実際には不要です。コメントを参照してください。グルーバー、以下)
    • 変数宣言、SELECTクエリなど、いくつかの部分を適切に指定する必要があります

    より一般的には:カーソルの必要性を回避しようとする

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

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



    1. テーブル内のすべての列を検索するにはどうすればよいですか?

    2. バインド変数を使用してDMLを挿入します:即時ステートメントの実行の句を使用します

    3. データベースを開始する前に尋ねる質問

    4. INNER JOIN状態で「OR」を使用するのは悪い考えですか?