e-learning、オラクル研修、LMS(学習管理システム)のiStudy

e-learning、オラクル研修、LMS(学習管理システム)のiStudy

第50回 「UTL_FILEパッケージでのファイル入力」

2013.03.11

こんにちは。インストラクターの蓑島です。3月に入りすこし春らしくなってきましたね。

前回(第50回)、UTL_FILEパッケージを使った【ファイル出力(書き込み)】を解説しましたが、今回は、UTL_FILEパッケージを使った【ファイル入力(読み込み)】を解説します。

では、前回出力した DATA_PUMP_DIRディレクトリのtest.txtファイルをUTL_FILEパッケージを使って読み込んでみます。読み込んだデータで画面出力をします。

以下をご覧ください。
前回のコードと比較すると違いが分かりやすいです。

SQL> SET SERVEROUTPUT ON       -- SQL*Plusの画面出力を有効
SQL> DECLARE
  2     /*   ファイルハンドルの宣言       */
  3     FH   UTL_FILE.FILE_TYPE;
  4     /*  読み込んだ行を格納する変数の宣言 */
  5     V_LINE   VARCHAR2(32767);
  6  --
  7  BEGIN
  8     /* 読込モード(R)で ファイルオープン ⇒ ファイルハンドル取得   */
  9     FH := UTL_FILE.FOPEN('DATA_PUMP_DIR','test.txt','R');
 10  --
 11     LOOP
 12          /*   そのファイルハンドルから1行読む      */
 13          UTL_FILE.GET_LINE(FH,V_LINE);
 14          /*   その行を画面に表示する    */
 15          DBMS_OUTPUT.PUT_LINE(V_LINE);
 16     END LOOP;     -- 上記の処理を繰り返す
 17  --
 18  EXCEPTION
 19     WHEN   NO_DATA_FOUND  THEN
 20          /*   最後にファイルをクローズする    */
 21          UTL_FILE.FCLOSE(FH);
 22  END;
 23  /
こんにちは。   ←※ファイルに書かれていた内容です。
お元気ですか?

PL/SQLプロシージャが正常に完了しました。

では前回と違う点を重点的に解説します。

●(1)読み込んだデータを格納する変数の宣言(5行目)

ファイルからデータを読み込みますので、読み込んだデータを格納する変数が必要です。
上記の例で5行目がその変数の定義です。V_LINEという変数をVARCHAR2(32767)で宣言しました。
サイズ32767は、PL/SQLプログラムにおけるVARCHAR2の最大サイズです。
32767でなければいけないというわけではありません。

●(2)読込モードでファイルをオープンする(9行目)

前回と違って今回は読込モードでオープンします。
ポイントは、オープンモードが 'R'であるという点です。
これによりそのファイルを読み込むことができます。(ちなみに書き込みモードは'W'でしたね)

●(3)1行読み込む(13行目)

UTL_FILE.GET_LINEで、1行分のデータを変数に読み込むことができます。
構文は以下の通りです。

   UTL_FILE.GET_LINE(ファイルハンドル, 変数);

(ちなみに、書き込みモードでは、1行書くとき、 UTL_FILE.PUT_LINEでしたね)

●(4) すべての行を読み込んだ終了判定処理(19行目)

UTL_FILE.GET_LINEの読み込みで終了判定処理はすこし独特なので要注意です。
まず、11~16行目のループ処理をよくご覧ください。
ファイルハンドルから1行読み込み、その行を画面表示することをループ処理で繰り返しています。
この処理を見てなにか変だと思いませんか?
 終了判定処理がないですよ!?

通常、基本ループ構文( LOOP  ~ END LOOP;)の中で、終了条件を判定しループから抜ける(EXIT)処理を記述していないと無限ループになります。
しかし上記の処理は無限ループにはなりません。
なぜかというと、UTL_FILE.GET_LINEが、ファイルの終端を超えてデータを読み込もうとすると、エラーとなるからです。PL/SQLではエラーが発生すると、例外処理部(EXCEPTION)に飛びます。
したがって、ループをEXITする処理を記述していなくても、無限ループにならないわけです。
そしてこの場合のエラーは、「NO_DATA_FOUND例外」です。
したがって、例外処理部のNO_DATA_FOUND例外ハンドラ(19行目)でファイルをクローズしているわけです。

「NO_DATA_FOUND例外」というと、代表的なケースは、SELECT ~INTO文が、0行の時のエラーですが、UTL_FILE.GET_LINEがファイルの終端を超えて読み込んだ場合も同じエラーなのです。

このように、最後の終了判定がすこし独特でなので注意してください。

それでは今回はここまでとします。また次回、ご期待ください。

先頭へ戻る