質問: ### 前提・実現したいこと Oracle database 12c と、SQL Developerを使用してPL/SQLの勉強中です。 UTL_FILEを使用して、ファイルの読み書きをしたいのですが、うまくいきませんでした。 作業&実行ユーザ:SCOTT(一般ユーザ) OS:Windows7 作業: SQL Developer(PL/SQL作成と実行) コマンドプロンプトよりSQL*Plus(sysdba権限で権限付与) エンジニア経験も浅い初心者ですが、 よろしくお願い致します。 ### 発生している問題・エラーメッセージ データベースorcl.domainに接続中です。 ORA-29283: 無効なファイル操作です。 ORA-06512: "SYS.UTL_FILE", 行536 ORA-29283: 無効なファイル操作です。 ORA-06512: "SCOTT.FILE_UNLOAD_DEPT", 行9 ORA-06512: 行2 プロセスが終了しました。 データベースorcl.domainから切断中です。。 ### UTL_FILE_DIR使用の場合 ``` create or replace PROCEDURE UTL_FILE_DIR_WRITE_SAMPLE AS file_hand UTL_FILE.FILE_TYPE; dirname VARCHAR2(250); name VARCHAR2(250); BEGIN name := 'dept.txt'; dirname := 'C:\Users\ymrkm\Desktop\SCOTT'; file_hand := UTL_FILE.FOPEN(dirname ,name,'w', 32767); UTL_FILE.PUT_LINE(file_hand, 'hoge'); UTL_FILE.FCLOSE(file_hand); END; ``` ``` **実行時のエラーメッセージ** データベースorcl.domainに接続中です。 ORA-29283: 無効なファイル操作です。 ORA-06512: "SYS.UTL_FILE", 行536 ORA-29283: 無効なファイル操作です。 ORA-06512: "SCOTT.FILE_UNLOAD_DEPT", 行9 ORA-06512: 行2 プロセスが終了しました。 データベースorcl.domainから切断中です。 ``` ### DIRECTORYオブジェクト使用の場合 ``` CREATE OR REPLACE PROCEDURE file_unload_dept IS CURSOR dept_cur IS SELECT dname FROM dept; file_hand UTL_FILE.FILE_TYPE; name VARCHAR2(20); BEGIN SELECT sysdate INTO day FROM dual; name:='dept.txt'; file_hand:=UTL_FILE.FOPEN('UTL_DATA',name,'a'); FOR dept_rec IN dept_cur LOOP UTL_FILE.PUT_LINE(file_hand,dept_rec.dname); END LOOP; UTL_FILE.FCLOSE(file_hand); END; ``` ``` **実行時のエラーメッセージ** データベースorcl.domainに接続中です。 ORA-29283: 無効なファイル操作です。 ORA-06512: "SYS.UTL_FILE", 行536 ORA-29283: 無効なファイル操作です。 ORA-06512: "SCOTT.FILE_UNLOAD_DEPT", 行9 ORA-06512: 行2 プロセスが終了しました。 データベースorcl.domainから切断中です。 ``` ### 試したこと ・CREATE DIRECTORY -> SCOTTにディレクトリの権限付与 ・SQL*PlusでSCOTTに接続し、SQL*Plusでfile_unload_deptを実行 ・システム権限を再度付与(CREATE SESSION,ALTER SESSION,CREATE PROCEDURE,CREATE TRIGGER,CREATE SEQUENCE) ・'dept.txt'をあらかじめ用意してみた ### (追記)試したこと UTL_FILE_DIRにディレクトリをセットし、 GRANT SELECT ON V_$PARAMETER2 TO SCOTT;もやってみたのですが、同様でした。 'dept.txt'が存在している状態で、FOPEN()の引数を'a'->'w'に変更したところ、 ORA-06512: "SYS.UTL_FILE", 行41 がなくなったのですが、他はそのままエラーとなっています。 ### 確認したこと(DIRECTORYオブジェクト) (1)UTL_FILE.OPENの第一引数は「DIRECTORYオブジェクト」 ``` "select * from all_directories;"より OWNER: SYS DIRECTORY_NAME: UTL_DATA DIRECTORY_PATH: C:\Users\ymrkm\Desktop\SCOTT ORIGIN_CON_ID: 0 ``` (2)UTL_FILE.OPENの第ニ引数は「DIRECTORYオブジェクト」配下となるファイル名 `C:\Users\ymrkm\Desktop\SCOTT\dept.txtのdept.txt` (3)上記DIRECTORYオブジェクトに対してスキーマが読み書きの権限があるか ``` GRANTEE: SCOTT OWNER: SYS TABLE_NAME: UTL_DATA GRANTOR: SYS PRIVILEGE: READ GRA: NO HIE: NO COM: NO TYPE: DIRECTORY ``` ``` GRANTEE: SCOTT OWNER: SYS TABLE_NAME: UTL_DATA GRANTOR: SYS PRIVILEGE: WRITE GRA: NO HIE: NO COM: NO TYPE: DIRECTORY ``` **以上です。** **よろしくお願い致します。**
回答: 未検証ですので外しているかもしれませんが、以下の条件が満たされているか確認して見てください。 * UTL_FILE.OPENの第一引数は「DIRECTORYオブジェクト」 * UTL_FILE.OPENの第ニ引数は「DIRECTORYオブジェクト」配下となるファイル名 * 上記DIRECTORYオブジェクトに対してスキーマが読み書きの権限があるか * UTL_FILE.OPENで利用するファイルに対して、Oracle実行ユーザにOSレベルで読み書き権限があるか また、Oracle12cでは`UTL_FILE_DIR`の利用よりも`DIRECTORYオブジェクト`の利用が推奨されているようです。 http://docs.oracle.com/cd/E49329_01/appdev.121/b71281/u_file.htm セキュリティ・モデル ※質問文のソースコードはコードタグでくくると読みやすくなりますよ。 ``` CREATE OR REPLACE .... // hogehoge ```