UTL_FILE.FOPEN() процедура не принимает путь для каталога?
Я пытаюсь записать файл, хранящийся на диске c:\ с именем vin1.txt, и получаю эту ошибку. Пожалуйста, предложите!
> 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
6 ответов
Начиная с 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
/
Объекты каталога требуют точного пути к файлу и не принимают подстановочные знаки. При таком подходе мы передаем имя объекта каталога...
UTL_FILE.FOPEN('TEMP_DIR', 'vineet.txt', 'W');
UTL_FILE_DIR устарела, поскольку по своей сути небезопасна - все пользователи имеют доступ ко всем каталогам ОС, указанным в пути, тогда как права на чтение и запись могут быть предоставлены отдельным пользователям отдельно. Кроме того, с объектами Каталога мы можем добавлять, удалять или изменять каталоги, не возвращая базу данных.
В любом случае, oracle
Пользователь ОС должен иметь права на чтение и / или запись в каталоге ОС. Если это не очевидно, это означает, что каталог должен быть виден с сервера базы данных. Поэтому мы не можем использовать любой из этих подходов для предоставления каталога на локальном ПК процессу, выполняющемуся на удаленном сервере базы данных. Файлы должны быть загружены на сервер базы данных или на общий сетевой диск.
Если oracle
Пользователь ОС не имеет соответствующих привилегий в каталоге ОС, или, если путь, указанный в базе данных, не совпадает с фактическим путем, программа выдаст это исключение:
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.
Не забывайте также, что путь к файлу находится на фактической машине сервера Oracle, а не на любой локальной машине разработки, которая может вызывать вашу хранимую процедуру. Это, наверное, очень очевидно, но кое-что следует помнить.
Вам необходимо зарегистрировать каталог в 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');
Имя каталога, похоже, чувствительно к регистру. Я столкнулся с той же проблемой, но когда я указал имя каталога в верхнем регистре, это сработало.
Для utl_file.open(местоположение, имя файла, режим) нам нужно указать имя каталога для местоположения, но не путь. Например:DATA_FILE_DIR, это имя каталога и проверьте путь к каталогу для этого конкретного имени каталога.
Вам нужно, чтобы ваш администратор БД изменил файл init.ora, добавив каталог, к которому вы хотите получить доступ, к параметру utl_file_dir. Затем ваш экземпляр базы данных нужно будет остановить и перезапустить, потому что init.ora читается только при запуске базы данных.
Вы можете просмотреть (но не изменить) этот параметр, выполнив следующий запрос:
SELECT *
FROM V$PARAMETER
WHERE NAME = 'utl_file_dir'
Поделитесь и наслаждайтесь.