2010-05-01 2 views
19

Я пытаюсь записать в файл, хранящийся в каталоге c: \ vin1.txt , и получить эту ошибку. Пожалуйста, предложите!UTL_FILE.FOPEN() процедура не принимает путь к каталогу?

> ERROR at line 1: ORA-29280: invalid 
> directory path ORA-06512: at 
> "SYS.UTL_FILE", line 18 ORA-06512: at 
> "SYS.UTL_FILE", line 424 ORA-06512: at 
> "SCOTT.SAL_STATUS", line 12 ORA-06512: 
> at line 1 

ЗДЕСЬ код

create or replace procedure sal_status 
    (
    p_file_dir IN varchar2, 
    p_filename IN varchar2) 
    IS 
    v_filehandle utl_file.file_type; 
    cursor emp Is 
     select * from employees 
     order by department_id; 
    v_dep_no departments.department_id%TYPE; 
    begin 
     v_filehandle :=utl_file.fopen(p_file_dir,p_filename,'w');--Opening a file 
     utl_file.putf(v_filehandle,'SALARY REPORT :GENERATED ON %s\n',SYSDATE); 
     utl_file.new_line(v_filehandle); 
     for v_emp_rec IN emp LOOP 
      v_dep_no :=v_emp_rec.department_id; 
      utl_file.putf(v_filehandle,'employee %s earns:s\n',v_emp_rec.last_name,v_emp_rec.salary);      
     end loop; 
     utl_file.put_line(v_filehandle,'***END OF REPORT***'); 
     UTL_FILE.fclose(v_filehandle); 
    end sal_status; 

execute sal_status('C:\','vin1.txt');--Executing 

ответ

32

Так как Oracle 9i там являются двумя способами или объявлением каталога для использования с UTL_FILE.

Старшим способом является установка параметра INIT.ORA UTL_FILE_DIR. Мы должны перезапустить базу данных, чтобы изменения повлияли на них. Значение может походить на любую другую переменную PATH; он принимает подстановочные знаки. Использование этого подхода означает прохождение пути к каталогу ...

UTL_FILE.FOPEN('c:\temp', 'vineet.txt', 'W'); 

Альтернативный подход заключается в объявлении объекта каталога.

create or replace directory temp_dir as 'C:\temp' 
/

grant read, write on directory temp_dir to vineet 
/

Объекты Directory требуют точного пути к файлу и не принимают подстановочные знаки. При таком подходе мы передаем имя объекта каталога ...

UTL_FILE.FOPEN('TEMP_DIR', 'vineet.txt', 'W'); 

UTL_FILE_DIR является устаревшим, поскольку он небезопасен - все пользователи имеют доступ ко всем каталогам ОС, указанных в пути, в то время как привилегии чтения и записи могут отменить предоставляемые дискретно отдельным пользователям. Кроме того, с объектами Directory мы можем добавлять, удалять или изменять каталоги, не отскакивая от базы данных.

В любом случае пользователь ОС oracle должен иметь права на чтение и/или запись в каталоге ОС. В случае, если это не очевидно, это означает, что каталог должен быть виден с сервера базы данных. Поэтому мы не можем использовать какой-либо подход, чтобы открыть каталог на нашем локальном ПК для процесса, выполняющегося на удаленном сервере базы данных. Файлы должны быть загружены на сервер базы данных или общий сетевой диск.


Если пользователь oracle OS не имеет соответствующих прав на каталог ОС, или если путь, указанный в базе данных не совпадает с фактической траектории, программа будет швырять это исключение:

ORA-29283: invalid file operation 
ORA-06512: at "SYS.UTL_FILE", line 536 
ORA-29283: invalid file operation 
ORA-06512: at line 7 

OERR текст этой ошибки довольно ясно:

29283 - "invalid file operation" 
*Cause: An attempt was made to read from a file or directory that does 
      not exist, or file or directory access was denied by the 
      operating system. 
*Action: Verify file and directory access privileges on the file system, 
      and if reading, verify that the file exists. 
+0

Можете ли вы присоединиться к другим каталогам? например: UTL_FILE.FOPEN ('TEMP_DIR' || '/ otherFolder', 'vineet.txt', 'W'); Я хочу знать, если это возможно. PATH OF FTP SERVER/.../... / – delive

0

Вы должны иметь ваш DBA изменить файл init.ora, добавив каталог, который вы хотите получить доступ к параметру «utl_file_dir». Затем ваш экземпляр базы данных должен быть остановлен и перезапущен, поскольку init.ora считывается только при создании базы данных.

Вы можете просматривать (но не изменять) этот параметр, выполнив следующий запрос:

SELECT * 
    FROM V$PARAMETER 
    WHERE NAME = 'utl_file_dir' 

Делите и наслаждайтесь.

3

Необходимо, чтобы register the directory с Oracle. fopen принимает имя объекта каталога, а не путь. Например:

(возможно, потребуется войти в систему как SYS выполнить эти)

CREATE DIRECTORY MY_DIR AS 'C:\'; 

GRANT READ ON DIRECTORY MY_DIR TO SCOTT; 

Затем, вы можете обратиться к нему в вызове FOPEN:

execute sal_status('MY_DIR','vin1.txt'); 
+0

Примечание: этот метод недоступен в старых версиях Oracle (до 9, я думаю), где вам может потребоваться установить utl_file_dir. Я думаю, –

5

не забывайте также о том, что путь к файлу на фактической машине оракул сервера, а не какой-либо лока л, который может вызвать вашу хранимую процедуру. Это, вероятно, очень очевидно, но что-то, о чем следует помнить.

1

Для utl_file.open (location, filename, mode) нам нужно указать имя каталога для местоположения, но не путь. Например: DATA_FILE_DIR, это имя каталога и проверьте путь к каталогу для данного имени каталога.

0

Название каталога, похоже, чувствительно к регистру. Я столкнулся с той же проблемой, но когда я указал имя каталога в верхнем регистре, он работал.

Смежные вопросы