ORA-24247错误本质是Oracle 11g+强制实施的细粒度网络访问控制:使用UTL_HTTP等包必须通过ACL显式授权用户(principal大小写敏感且须真实存在)、目标host(精确匹配,非URL)、端口范围,并同时授予'resolve'和'connect'权限,且操作后必须COMMIT。

ORA-24247 错误本质不是权限缺失,而是 Oracle 11g 及以后版本强制要求:**任何使用 UTL_HTTP、UTL_SMTP、UTL_INADDR、UTL_TCP 等网络包的用户,必须显式通过 ACL 授权目标主机和端口**。没配 ACL,哪怕有 EXECUTE 权限也报错。
ACL 创建时 principal 大小写敏感且必须存在
你指定的 principal(即用户名)必须是数据库中真实存在的用户,且区分大小写。常见错误是传入小写用户名(如 'test'),而实际用户是 'TEST' —— 这会导致后续 ADD_PRIVILEGE 或 ASSIGN_ACL 执行成功但权限不生效。
-
principal值建议用UPPER('username')包裹,或直接查dba_users.username确认拼写 - 不能对角色(如
'CONNECT')或不存在用户赋 ACL 权限 -
CREATE_ACL只注册 ACL 文件名,不校验principal是否真实存在 —— 错误会延迟暴露在运行时
assign_acl 的 host 和端口必须匹配实际调用目标
ASSIGN_ACL 中的 host 参数不是“通配符占位符”,而是**精确匹配规则**:如果 PL/SQL 调用 UTL_HTTP.REQUEST('http://api.example.com:8080/health'),那么 host 必须设为 'api.example.com'(不能写 'http://api.example.com' 或 'api.example.com:8080'),lower_port 和 upper_port 必须覆盖 8080。
- 用
'*'可匹配任意主机,但仅限测试环境;生产环境应锁定具体域名或 IP - 端口范围要包含实际连接端口,例如 SMTP 是 25 或 587,HTTP 是 80/443,自定义服务需填对应端口
-
host => 'localhost'在 Oracle 不在本机部署时无效 —— 它解析的是数据库服务器自身的localhost,不是客户端机器
resolve 和 connect 权限缺一不可
多数网络操作需要两个基础权限:'resolve'(DNS 解析主机名)和 'connect'(建立 TCP 连接)。只授 'connect' 会导致 ORA-29257(未知主机);只授 'resolve' 则无法真正发请求。
-
resolve权限必须通过DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE单独添加,CREATE_ACL里指定的privilege只影响首次创建时的默认权限项 - 若目标地址是 IP(如
'10.1.2.3'),resolve权限可省略;但一旦代码中用了域名,就必须有 - 权限授予对象是同一个
principal,且is_grant => TRUE
ACL 配置后必须 commit 且无法热生效
所有 DBMS_NETWORK_ACL_ADMIN 过程执行后,**必须显式 COMMIT**,否则权限不会持久化,下次会话仍报错。另外 ACL 生效有缓存,修改后可能需等待数秒,或执行 EXEC DBMS_NETWORK_ACL_ADMIN.CACHE_FLUSH 强制刷新(Oracle 12c+ 支持)。
- 不要在匿名块里漏掉
COMMIT—— 这是最常见的“明明执行了却没效果”的原因 - ACL 修改不触发即时生效,已有连接可能仍走旧规则;新会话或重连后才应用新配置
- 验证是否生效:用目标用户登录,执行简单测试,如
BEGIN UTL_HTTP.REQUEST('http://www.baidu.com'); END;
ORA-24247 就照常报。


















