PL/SQLを使ってみよう

第49回 「UTL_FILEパッケージでのファイル出力」(2013.02.18)

 

こんにちは。インストラクターの蓑島です。

前回からUTL_FILEパッケージでファイルに入出力する方法について解説しています。
まず前回は雰囲気だけ、ということで簡単なファイル出力のサンプルコードを掲載しました。
今回はそのサンプルコードを詳しく解説します。
以下は前回のサンプルコードと同じ内容ですが、わかりやすくコメントをつけたものです。
ファイルに出力する簡単な例です。

test.txtというファイルに

--------------------
こんにちは。
お元気ですか?
--------------------

と書き込みます。

SQL> DECLARE
  2     /*   ファイルハンドルの宣言       */
  3     FH   UTL_FILE.FILE_TYPE;
  4  --
  5  BEGIN
  6     /*  ファイルオープン ⇒ ファイルハンドル取得   */
  7     FH := UTL_FILE.FOPEN('DATA_PUMP_DIR','test.txt','W');
  8  --
  9     /*   そのファイルハンドルで1行書く      */
 10     UTL_FILE.PUT_LINE(FH,'こんにちは。');
 11  --
 12     /*  さらにもう1行書く       */
 13     UTL_FILE.PUT_LINE(FH,'お元気ですか?');
 14  --
 15     /*   最後にファイルをクローズする    */
 16     UTL_FILE.FCLOSE(FH);
 17  END;
 18  /

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


では解説します。

(1)ファイルハンドルの宣言(3行目)

まず、ファイルを扱うためには、ファイルごとにファイルハンドルというものが必要です。
事前に宣言部でそれを格納する変数を宣言しておきます。構文は以下の通りです。

      ファイルハンドラ変数   UTL_FILE.FILE_TYPE;

つまり、UTL_FILEパッケージのFILE_TYPE型でファイルハンドルの変数を宣言するわけです。

(2)ファイルをオープンし、ファイルハンドルを取得(7行目)

次に、ファイルをオープンし、そのファイルのファイルハンドルを上記(1)の変数に取得します。
構文は以下の通りです。

     ファイルハンドル変数 
        := UTL_FILE.FOPEN('ディレクトリオブジェクト名','ファイル名','モード');

ここで、ディレクトリオブジェクトの意味ですが、これはサーバー上のディレクトリに対して付けた名前のことです。
あらかじめ管理者が必要に応じて作成して、必要なユーザに必要な権限(READ権限、WRITE権限)を与えておきます。
これにより、しかるべきユーザだけが、しかるべきディレクトリに対して、読む(READ)また書く(WRITE)ことができるわけです。セキュリティ対策ですね。
例えば、サンプルコードでは、'DATA_PUMP_DIR'というディレクトリオブジェクト名になっていますが、これが具体的にどこの場所であるかを調べるには、以下のような問合わせで可能です。

SQL> SELECT DIRECTORY_PATH FROM ALL_DIRECTORIES
  2  WHERE  DIRECTORY_NAME = 'DATA_PUMP_DIR';

DIRECTORY_PATH
----------------------------------------------------------------------
C:\u01\app\oracle\admin\orcl\dpdump\

そうすると、'DATA_PUMP_DIR'の実際のディレクトリは、
'C:\u01\app\oracle\admin\orcl\dpdump\' であることがわかります。
このディレクトリは『サーバー上のディレクトリであり、クライアント側のディレクトリではない』ことに注意してください。

上の問い合わせで、ALL_DIRECTORIESというデータディクショナリビューは、自分が権限を持つディレクトリオブジェクトを調べるときに使います。
そして更に自分が、そのディレクトリオブジェクトに対して、READ権限を持つのか、WRITE権限をもつのかを調べる場合は次のような問い合わせで調べることができます。

SQL> SELECT TABLE_NAME, PRIVILEGE FROM USER_TAB_PRIVS_RECD
  2  WHERE  TABLE_NAME = 'DATA_PUMP_DIR'
  3  /

TABLE_NAME                     PRIVILEGE
----------------------------------------------------------------------
DATA_PUMP_DIR                  WRITE
DATA_PUMP_DIR                  READ

上の結果では、私は'DATA_PUMP_DIR'ディレクトリに対してWRITE権限とREAD権限を持つことがわかります。

次にファイル名ですが、サンプルコードでは、'test.txt'です。
これは実際にこの通りのファイル名を意味します。

次にモードですが、モードの意味は以下の通りです。

   R   → 読み込むためのオープン(Read)
   W   → 書き込むためのオープン(Write)
   A   → 追加書き込ののためのオープン(Append)

サンプルコードではモードは'W'ですが、これは書き込むためのオープンを表しているわけです。


(3)ファイルハンドを指定してそのファイルに書き込む(10行目、13行目)

  UTL_FILE.PUT_LINE(ファイルハンドル,文字列);

これによりファイルハンドルの示すファイルに、指定された文字列を書くことができます。

参考までに、書き出しについて代表的なものをまとめると以下の通りです。

    UTL_FILE.PUT_LINE(ファイルハンドル、文字列);
                        →  最後に改行コードを付けて書く(つまり1行)

  UTL_FILE.PUT(ファイルハンドル、文字列);
                        → 改行コードを付けないで書く

  UTL_FILE.NEW_LINE(ファイルハンドル)
                        → 改行コードのみを書く

例えば'ABC'をPUTで書いて、次に'DEF'をPUTで書いて、最後にNEW_LINEで改行コードを書くと'ABCDEF'という1行になります。

PUT_LINEは、PUT + NEW_LINEと同じことであり、1行として書き出しできるのでもっともよく使われます。
またNEW_LINEだけを単独で実行すると、1行空けることができます。

(4)ファイルクローズ (16行目)

ファイルは、必ず最後にクローズする必要があります。

  UTL_FILE.FCLOSE(ファイルハンドル)

これにより指定されたファイルがクローズされて、他のアプリケーションで使用可能になります。

以上がファイルに書く場合の詳細です。
ファイルを書ける場所は、『サーバー側』のディレクトリであることに注意してください。

では、次回はファイルを読む場合の詳細について解説します。ご期待ください。

著者プロフィール

minoshima_

蓑島 好昭(Minoshima Yoshiaki)

Oracle認定講師、IBM認定講師。当会場では貴重な男性講師。システム開発や設計業務経験があるからこそ、「受講生の皆さんには苦労して欲しくない!」と講義にも熱が入る。データベースを中心とした技術分野に設計、管理、開発と幅広いスキルをもつ。   →詳しいプロフィールはこちら