必须先授予create any directory权限才能创建directory,否则报ora-01031;read和write权限须分别授予且不可用all;sql授权后还需确保os层oracle用户对路径有对应权限,严禁授给public。

CREATE ANY DIRECTORY 权限必须先有,否则连建目录都做不到——这是第一步卡点,不是“授权后没效果”,而是根本走不到授权那步。
CREATE DIRECTORY 之前必须确认谁有 CREATE ANY DIRECTORY
普通用户哪怕有 DBA 角色,也无法执行 CREATE DIRECTORY;报错一定是 ORA-01031: insufficient privileges。解决方式只有一种:由 SYS 或 SYSTEM 执行:GRANT CREATE ANY DIRECTORY TO username;
注意:该权限不能回收自 DBA 角色,必须显式授予;也不建议长期赋予,用完即 revoke。
GRANT READ ON DIRECTORY 和 GRANT WRITE ON DIRECTORY 必须分开写
常见错误是写成 GRANT ALL ON DIRECTORY my_dir TO user1; —— Oracle 不认 ALL,也不支持 EXECUTE(那是误抄 PL/SQL 包权限)。真正有效的只有:GRANT READ ON DIRECTORY my_dir TO user1;GRANT WRITE ON DIRECTORY my_dir TO user1;
漏掉 READ,外部表或 UTL_FILE.GET_LINE 就会报 ORA-29283: invalid file operation;漏掉 WRITE,UTL_FILE.PUT_LINE 或 expdp 写日志就会失败。两者互不替代。
OS 层权限和 Oracle 进程身份必须对得上
即使 SQL 层 GRANT 成功,UTL_FILE.fopen 仍可能报 ORA-29280: invalid directory path 或 ORA-29283,本质是 Oracle 后台进程(通常是 OS 用户 oracle)在系统层面打不开那个路径。
验证方法:
• Linux 下跑:sudo -u oracle ls -ld /path/to/dir
• 确保目录存在、属主为 oracle 或所在组可读写(如 chmod 755 或 775)
• Windows 下检查 Oracle 服务运行账户(非你当前登录账户)是否有 NTFS 读写权限
• 如果路径在 ASM 或 ACFS 上,ls 能看到不代表 Oracle 进程能访问,需确认磁盘组已挂载且路径被 export
别把 READ/WRITE 授给 PUBLIC 或泛化角色
GRANT READ, WRITE ON DIRECTORY tmp_dir TO PUBLIC; 看似省事,实则危险:
• 任意数据库用户都能通过 UTL_FILE 往服务器任意位置写文件
• 可覆盖关键配置(如 listener.ora)、写入恶意脚本、甚至触发某些解析逻辑(虽少见但真实)
• 生产环境应坚持最小权限:一个应用一个 DIRECTORY,只授给具体作业账号
• 定期审计执行:SELECT grantee, privilege FROM DBA_TAB_PRIVS WHERE TABLE_NAME = 'MY_DIR' AND PRIVILEGE IN ('READ','WRITE');











