Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

SQLのfetchについてまとめています。サンプルのストアドプロシジャを使って解説。

fetchは、select結果を順に取り出すSQL

fetchは、ストアドプロシジャ内で指定したSQLを実行して一件づつデータを取得し変数に格納するために使われるSQLコードです。

以下のSQLは、2つのテーブルから値を一件づつfetchして取得し、別のテーブルに値をinsertするMySQL用のサンプルです。

DELIMITER //
CREATE PROCEDURE curdemo()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE a CHAR(16);
  DECLARE b, c INT;
  DECLARE cur1 CURSOR FOR SELECT id,data FROM test.t1;
  DECLARE cur2 CURSOR FOR SELECT i FROM test.t2;
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;
  OPEN cur2;

  read_loop: LOOP
    FETCH cur1 INTO a, b;
    FETCH cur2 INTO c;
    IF done THEN
      LEAVE read_loop;
    END IF;
    IF b < c THEN
      INSERT INTO test.t3 VALUES (a,b);
    ELSE
      INSERT INTO test.t3 VALUES (a,c);
    END IF;
  END LOOP;

  CLOSE cur1;
  CLOSE cur2;
END;
//

DELIMITER ;

declareでselect文から一件づつ取得するためのカーソルを定義し、ループ処理中でカーソルからローカル変数a,b,cに値を取得しています。

MySQLでは、データが見つからなかった場合にNOT FOUNDのステータスを返します。以下のdeclareで継続条件を指定しています。

  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

データが見つからなかった場合の判定方法は、データベースによって異なるようです。

【関連記事】
SQLのdeclareは、ストアドプロシジャ内のローカル変数宣言をおこなう

fetchは、標準SQLで、カーソル定義・操作用のSQLとして定められています。カーソルは、データベースサーバ側にある結果集合と取得する行の位置を示すもので、主にアプリケーションプログラムなどの手続き型言語からSQL実行用に利用します。

fetchを実行すると、カーソルのポインタが示す位置の行データを取得し、ポインタを一行文進めます。

主要なデータベースでは、ストアドプロシジャ内で使用することも多いようです。

【関連記事】
SQLとはどういうもの? 独自拡張と標準SQLの大きな違いって、何?

OracleのFetchの注意点

以下は、Oracleでfetchを使ってデータを順次読み出しするサンプルです。fetchでデータが見つからなかったときの処理に注意が必要です。

 DECLARE
     l_total INTEGER := 10000;

     CURSOR employee_id_cur
     IS
          SELECT employee_id
            FROM plch_employees
        ORDER BY salary ASC;

     l_employee_id   employee_id_cur%ROWTYPE;
  BEGIN
     OPEN employee_id_cur;

     LOOP
        FETCH employee_id_cur INTO l_employee_id;
        EXIT WHEN employee_id_cur%NOTFOUND;

        assign_bonus (l_employee_id, l_total);
        EXIT WHEN l_total <= 0;
     END LOOP;

     CLOSE employees_cur;
  END;

Oracleでは、問い合わせで1行も見つからなかったときに、NO_DATA_FOUNDが発生しません。代わりにcursor_name%NOTFOUND属性がTRUEになります。

このため、データが見つからずループを抜ける処理で、以下のように記述しています。

        EXIT WHEN employee_id_cur%NOTFOUND;

参考)Oracle Part 12:カーソルの操作

SQL ServerのFetchの注意点

SQL Serverのfetchサンプルは以下の通りです。

DECLARE vend_cursor CURSOR  
    FOR SELECT * FROM Purchasing.Vendor  
OPEN vend_cursor  
FETCH NEXT FROM vend_cursor;  

SQL Serverには、カーソル定義の書式に2種類あります。標準SQLに準拠した書式と、Transact-SQLの独自拡張の書式です。

//標準SQLの書式 
DECLARE cursor_name [ INSENSITIVE ] [ SCROLL ] CURSOR   
     FOR select_statement   
     [ FOR { READ ONLY | UPDATE [ OF column_name [ ,...n ] ] } ]  
[;]  
//Transact-SQL の拡張書式  
DECLARE cursor_name CURSOR [ LOCAL | GLOBAL ]   
     [ FORWARD_ONLY | SCROLL ]   
     [ STATIC | KEYSET | DYNAMIC | FAST_FORWARD ]   
     [ READ_ONLY | SCROLL_LOCKS | OPTIMISTIC ]   
     [ TYPE_WARNING ]   
     FOR select_statement   
     [ FOR UPDATE [ OF column_name [ ,...n ] ] ]  
[;]

参考)DECLARE CURSOR (Transact-SQL) – SQL Server | Microsoft Docs

PostgreSQLのFetchの注意点

PostgreSQLのFetchの書式は以下の通りです。

FETCH [ 方向 [ FROM | IN ] ] cursor_name

指定したカーソル(cur1)から最初の5行を取り出すには、以下のように指定します。

FETCH FORWARD 5 FROM cur1;

なお、FORWARDやBACKWORDなどの方向指定はPostgreSQLの拡張です。fetchのIN指定もPostgreSQLの拡張になります。標準SQLでは、FETCHのカーソル名の前に指定できるのはFROMのみです。

互換性に配慮してSQLコードを記述する際は注意しましょう。

まとめ

ポテパンダの一言メモ

[/commen]

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。