UTL_FILE.FOPEN() procedure not accepting path for directory?

Vineet picture Vineet · May 1, 2010 · Viewed 294.1k times · Source

I am trying to write in a file stored in c:\ drive named vin1.txt and getting this error .Please suggest!

> 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

HERE is the code

  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

Answer

APC picture APC · May 2, 2010

Since Oracle 9i there are two ways or declaring a directory for use with UTL_FILE.

The older way is to set the INIT.ORA parameter UTL_FILE_DIR. We have to restart the database for a change to take affect. The value can like any other PATH variable; it accepts wildcards. Using this approach means passing the directory path...

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

The alternative approach is to declare a directory object.

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

grant read, write on directory temp_dir to vineet
/

Directory objects require the exact file path, and don't accept wildcards. In this approach we pass the directory object name...

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

The UTL_FILE_DIR is deprecated because it is inherently insecure - all users have access to all the OS directories specified in the path, whereas read and write privileges can de granted discretely to individual users. Also, with Directory objects we can be add, remove or change directories without bouncing the database.

In either case, the oracle OS user must have read and/or write privileges on the OS directory. In case it isn't obvious, this means the directory must be visible from the database server. So we cannot use either approach to expose a directory on our local PC to a process running on a remote database server. Files must be uploaded to the database server, or a shared network drive.


If the oracle OS user does not have the appropriate privileges on the OS directory, or if the path specified in the database does not match to an actual path, the program will hurl this exception:

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

The OERR text for this error is pretty clear:

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.