今天項目上提了一個support,一個存儲過程報“ORA-29280: 目錄路徑無效”錯誤
改存儲過程中用到了UTL_FILE.fopen函數v_dat := UTL_FILE.fopen(v_datpath,v_datfile,'w');
UTL_FILE.fopen的作用是打開主機上某一目下的一個文件,向文件里寫入內容。
該函數與utl_file_dir有密切關系,查看問題主機該參數的值
SQL> show parameter utl_file_dir
NAME TYPE
------------------------------------ ----------------------
VALUE
------------------------------
utl_file_dir string
SQL>
該參數為空,導致
在initsid.ora文件中,加入或修改
設置utl_file_dir的要點:
1。 utl_file_dir=* 這表示你能操作任何目錄,盡量不要用
2。 utl_file_dir=d:\ 這表示你能操作d:\目錄下的文件,但你不能操作d:\目錄下的子目錄
3。注意在設置
utl_file_dir=路徑時,如果路徑是長路徑名,例如c:\my temp目錄,則你必須加上'',例如:
utl_file_dir='c:\my temp'
4。utl_file_dir可以是多個路徑
utl_file_dir=c:\,d:\,d:\temp,'c:\my temp'
5。設置完必須重新啟動數據庫
Sr上:ID 1063519.6
Cause
This error is caused by not using quotes when setting the UTL_FILE_DIR parameter within the init.ora database parameter file. As a result, the database reads the space as the beginning of a second directory.
Init.ora file setting:
----------------------------
utl_file_dir=d:\Program Files
When the database is started and the UTL_FILE_DIR is reviewed via SQL*Plus is it displayed as the following (notice the ',' instead of space):
SQL> show parameter utl_file_dir
NAME TYPE VALUE
----------- ------- -----------------------
utl_file_dir string d:\Program, Files
here are actually 2 solutions for this issue.
Solution 1:
-------------------
Use quotes when adding the directory to the init.ora file.
Init.ora file setting:
----------------------------
utl_file_dir='d:\Program Files'
When the database is restarted, the database will now view the space as part of the directory name.
SQL> show parameter utl_file_dir
NAME TYPE VALUE
----------- ------- -----------------------
utl_file_dir string d:\Program Files
Now when the anonymous block is executed it works.
SQL> set serveroutput on
SQL> DECLARE
2 file_location VARCHAR2(256) := 'd:\Program Files';
3 file_name VARCHAR2(256) := 'utlfile.txt';
4 file_text VARCHAR2(256) := 'Hello World';
5 file_id UTL_FILE.file_type;
6 BEGIN
7 file_id := UTL_FILE.fopen(file_Location, file_name, 'W');
8 UTL_FILE.put_line(file_id, file_text);
9 UTL_FILE.fclose(file_id);
10 EXCEPTION
11 WHEN UTL_FILE.INVALID_PATH
12 THEN dbms_output.put_line('Invalid path ' || SQLERRM);
13 WHEN OTHERS
14 THEN dbms_output.put_line('Others '|| SQLCODE || ' ' || SQLERRM);
15 END;
16 /
PL/SQL procedure successfully completed.
Reviewing the file from the command prompt should display the following:
D:\Program Files> type utlfile.txt
Hello World
Solution 2:
-----------------
Don't using the UTL_FILE_DIR database parameter.
Starting with version 9i of the Database the UTL_FILE_DIR has been deprecated. A Directory Alias should be used instead.
Instead of the UTL_FILE_DIR, a Directory Alias should be created. One advantage to using a Directory Alias is that the database does NOT have to be restarted before it can be used.
The following SQL illustrates an example. The Database user needs to have CREATE DIRECTORY privileges. Since the directory is passed as a string it would already have quotes which would prevent this error.
SQL> CREATE DIRECTORY DIR_WITH_SPACES AS 'D:\Program Files';
Directory created.
Once the Directory Alias has been created the code should use the Directory Alias instead of the actual path. Review the change to the UTL_FILE.fopen command.
DECLARE
file_name VARCHAR2(256) := 'utlfile.txt';
file_text VARCHAR2(256) := 'Hello World';
file_id UTL_FILE.file_type;
BEGIN
file_id := UTL_FILE.fopen('DIR_WITH_SPACES', file_name, 'W');
UTL_FILE.put_line(file_id, file_text);
UTL_FILE.fclose(file_id);
EXCEPTION
WHEN UTL_FILE.INVALID_PATH
THEN dbms_output.put_line('Invalid path ' || SQLERRM);
WHEN OTHERS
THEN dbms_output.put_line('Others '|| SQLCODE || ' ' || SQLERRM);
END;
/
PL/SQL procedure successfully completed.