UTL_FILE.FOPEN()过程不接受目录路径?

时间:2010-05-01 18:37:23

标签: oracle plsql oracle9i utl-file

我正在尝试写入存储在名为vin1.txt的c:\驱动器中的文件 并得到这个错误。请建议!

> 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 个答案:

答案 0 :(得分:35)

由于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已弃用,因为它本身就不安全 - 所有用户都可以访问路径中指定的所有操作系统目录,而读取和写入权限可以单独授予单个用户。此外,使用Directory对象,我们可以在不弹跳数据库的情况下添加,删除或更改目录。

在任何一种情况下,oracle OS用户必须在OS目录上具有读取和/或写入权限。如果不明显,这意味着该目录必须在数据库服务器中可见。因此,我们不能使用任何一种方法将本地PC上的目录公开给在远程数据库服务器上运行的进程。必须将文件上载到数据库服务器或共享网络驱动器。


如果oracle OS用户对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.

答案 1 :(得分:9)

不要忘记文件的路径是在实际的oracle服务器计算机上,而不是任何可能正在调用存储过程的本地开发计算机。这可能是非常明显的,但应该记住的事情。

答案 2 :(得分:4)

您需要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');

答案 3 :(得分:1)

对于utl_file.open(位置,文件名,模式),我们需要为位置而不是路径提供目录名称。例如:DATA_FILE_DIR,这是目录名,并检查该特定目录名的目录路径。

答案 4 :(得分:1)

目录名称似乎区分大小写。我遇到了同样的问题,但当我以大写字母提供目录名时,它起作用了。

答案 5 :(得分:0)

您需要让DBA修改init.ora文件,将要访问的目录添加到'utl_file_dir'参数中。然后需要停止并重新启动您的数据库实例,因为只有在启动数据库时才会读取init.ora。

您可以通过运行以下查询来查看(但不能更改)此参数:

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

分享并享受。