ORA-24247 根本原因是 Oracle 11g+ 引入的 ACL 网络访问控制未配置:必须用 DBMS_NETWORK_ACL_ADMIN 显式创建 ACL、授予 connect 和 resolve 权限、绑定精确 host/port 并 COMMIT,缺一不可。
oracle 存储过程调用 webservice 报 ora-24247 错误,根本原因不是代码写错、url 写错或网络不通,而是数据库层面没配 acl —— 这个权限控制独立于传统 grant,必须显式创建并绑定主机端口。
ORA-24247 是 ACL 缺失的明确信号
只要看到这个错误,就说明 UTL_HTTP 或 UTL_DBWS 被拦在了网络层。常见触发场景:
- 新建用户后直接跑 HTTP 请求,没做任何 ACL 配置
- ACL 创建了,但只加了
connect,没加resolve(尤其 URL 含域名时) -
ASSIGN_ACL的host值和实际请求目标不一致(比如请求api.example.com,ACL 却绑了example.com) - ACL 文件名重复覆盖了系统已有配置(如硬写
'utl_http.xml'且已存在)
principal 必须是大写用户名,不能是角色或小写名
DBMS_NETWORK_ACL_ADMIN.CREATE_ACL 的 principal 参数认的是真实数据库用户名,且默认建用户时是大写的。填错会直接报 ORA-46051 或静默失败:
- 用户是
APP_USER,必须写principal => 'APP_USER',写成'app_user'或'App_User'都无效 - 不能填角色名(如
'CONNECT'),哪怕该角色有EXECUTE ON UTL_HTTP也不行 - 用户还没
CREATE USER就去建 ACL,会失败;ACL 不会自动创建用户
域名场景下 resolve 权限不可省略
如果 WebService 地址含域名(如 https://svc.internal/api),Oracle 内部需 DNS 解析。仅授 connect 会导致后续报 ORA-29273 + ORA-12545(主机名无法解析):
- 必须分两步:先
CREATE_ACL加connect,再ADD_PRIVILEGE加resolve - 两个权限要属于同一个 ACL 文件(
acl => 'xxx.xml'一致) -
resolve不代表能连通,只是允许 Oracle 发起 DNS 查询;连通性仍取决于connect和ASSIGN_ACL的 host/port
ASSIGN_ACL 的 host 和端口必须精确匹配请求目标
host 不支持正则,只接受完整域名/IP 或通配符 *;lower_port/upper_port 是闭区间:
- 请求 URL 是
http://service.internal:8080/→host => 'service.internal',lower_port => 8080,upper_port => 8080 - HTTPS 默认端口 443,别漏掉;HTTP 默认 80 同理
-
host => '*'在测试环境可用,生产环境禁止——它绕过所有主机白名单控制 - 主机名大小写敏感:若 DNS 解析依赖
Api.Example.Com,ACL 里也得照写,不能简写为example.com
最易被忽略的一点:ACL 修改后必须 COMMIT,否则事务未提交,权限不生效。很多 DBA 在 SQL*Plus 里执行完 PL/SQL 块忘了敲 COMMIT,查 dba_network_acl_privileges 看起来都对,但就是报 ORA-24247。


















