PL/SQL で SELECT INTO を行なう
テーブル定義
テーブルは PLSQL による INSERT のテーブル定義をデータ使用
PL/SQL で SELECT を実行する
PL/SQL で SELECT を行なうには SELECT 〜 INTO を使用して SELECT の結果を変数に代入しなければならない。
SELECT だけを単独で記述すると以下のコンパイルエラーが出力される。
PLS-00428: INTO 句はこの SELECT 文に*入ります*。
(これは「要ります」の誤りと思われる)
PLS-00428: an INTO clause is expected in this SELECT statement (英文)
SELECT INTO を使用した単一行の取得
-- 実行してみる。
SQL> SET SERVEROUTPUT ON
SQL> CALL STEP01_SELECT();
利用者IDは0020です。
利用者名は小泉 純一さんです。
コールが完了しました。
しかし、このプログラムは抽出対象レコードが単一の場合しか使用できない。複数件になると以下のエラーが出力される。
SQL> INSERT INTO USER_MASTER ( USER_ID, USER_NAME) VALUES ('1000', 'おじゃまデータ');
1行が作成されました。
SQL> CALL STEP01_SELECT();
*
行1でエラーが発生しました。:
ORA-01422: 完全フェッチがリクエストよりも多くの行を戻しました
ORA-06512: "RIVUS.STEP01_SELECT", 行6
SQL> ROLLBACK;
ロールバックが完了しました。
複数のレコードを取り扱うには カーソル・ループ を使う方法と
コレクションを使用した バルク処理(バルクフェッチ) による方法がある。
大量のデータを一度に処理するケースではバルク処理の方が IO 回数が少ないために高速に処理を行うことができる。
SELECT INTO によるバルク処理
SELECT INTO による構文では単一行しか取り扱うことができないが SELECT BULK COLLECT INTO 構文を使用すると
比較的小さな結果セットを取り扱う場合に有用である。メモリで取り扱うには大きすぎる結果セットを取り扱う場合には バルクフェッチ の方がメモリ総使用量が少なくて済むためコストパフォーマンスが高い。
CREATE OR REPLACE PROCEDURE RIVUS.STEP01_SELECT_ALL
IS
TYPE tUserList IS TABLE OF USER_MASTER%ROWTYPE;
vUsers tUserList;
BEGIN
SELECT * BULK COLLECT INTO vUsers FROM USER_MASTER;
-- ↑ コレクション(ネストした表) vUsers にすべての結果が一度に設定される。
DBMS_OUTPUT.PUT_LINE('レコード数は' || vUsers.COUNT || '件です。');
DBMS_OUTPUT.PUT_LINE('利用者IDは' || vUsers(1).USER_ID || 'です。');
DBMS_OUTPUT.PUT_LINE('利用者名は' || vUsers(1).USER_NAME || 'さんです。');
vUsers.DELETE; -- 要らなくなったから解放
DBMS_OUTPUT.PUT_LINE('配列の大きさは' || vUsers.COUNT || 'です。');
END;
/
関連事項