[Oracle] UTL_FILEで共有フォルダにアクセスするとORA-29283が発生 | Archive Redo Blog

Archive Redo Blog

DBエンジニアのあれこれ備忘録

UTL_FILE を使ってファイルの入出力を行うプロシージャ等を作成する際、それを Linux 環境と Windows 環境の両方で使用するならば、パスの記述方法の違いをケアする必要があります。

呼び出し側から OS 固有の記述方法で記述されたパスを受け取ったり、入出力の前にパスを OS 固有の記述方法に変換したりと、その方法はいろいろ考えられますが、同じパスの記述方法で環境を問わずに入出力を行えればそれに越したことはありません。

例えば、Linux 環境では "/home/oracle"、Windows 環境では "c:\home\oracle" というフォルダにアクセスする場合、通常はそれぞれの OS にあった記述が必要ですが、Windows 環境において "c:\home" を "home" という共有名で共有設定すると、"/home/oracle" という記述方法で "c:\home\oracle" にアクセスすることができるようになります。

ところが...

10g ではこの方法でいけたのですが、11g では Windows 環境で以下のようなエラーが発生するようになりました。

SQL> DECLARE
  2     wk_file UTL_FILE.FILE_TYPE;
  3  BEGIN
  4  wk_file := UTL_FILE.FOPEN( '/home/oracle', 'test.txt', 'w', 32767 );
  5  UTL_FILE.PUT_LINE( wk_file, 'abc');
  6  UTL_FILE.FCLOSE( wk_file );
  7  END;
  8  /
DECLARE
*
行1でエラーが発生しました。:
ORA-29283: 無効なファイル操作です。
ORA-06512: "SYS.UTL_FILE", 行536
ORA-29283: 無効なファイル操作です。
ORA-06512: 行4

この例では、UTL_FILE_DIR 初期化パラメータに "*" を設定し、パスを直接指定していますが、DIRECTORY オブジェクトを定義しても同じでした。

パス区切り文字を "\" に変えてみても同じでした。


ところが、パスを "//server1/home/oracle" というふうにホスト名から記述するとうまくいきます。

SQL> DECLARE
  2     wk_file UTL_FILE.FILE_TYPE;
  3  BEGIN
  4  wk_file := UTL_FILE.FOPEN( '//server1/home/oracle', 'test.txt', 'w', 32767 );
  5  UTL_FILE.PUT_LINE( wk_file, 'abc');
  6  UTL_FILE.FCLOSE( wk_file );
  7  END;
  8  /

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


10g ではパスが "/" から始まる場合にホスト名を補完していたが、11g からは明示的に指定しなければならなくなったということなんでしょうかね。


そういえば、READMEにこんなことが書いてありましたが、

ファイルがシンボリック・リンクの場合、UTL_FILE パッケージでファイルを開くことができなくなりました。この新しい制限により、UTL_FILE パッケージの既知のセキュリティ・ホールがなくなりました。

ひょっとしたら Windows の共有フォルダもこの制限に当てはまるということなのかもしれません。


ということで、11g の場合は残念ながら OS の違いを意識せざるをえないようです。