revoke execute on utl_http 失败是因为必须指定 schema 前缀 sys,正确写法为 revoke execute on sys.utl_http from public;漏掉 sys. 会导致对象解析失败而非权限不存在。

REVOKE EXECUTE ON UTL_HTTP 为什么执行失败
直接写 REVOKE EXECUTE ON UTL_HTTP FROM PUBLIC 会报 ORA-00942: table or view does not exist。Oracle 要求必须带 schema 前缀,UTL_HTTP 属于 SYS,正确写法是 REVOKE EXECUTE ON SYS.UTL_HTTP FROM PUBLIC。漏掉 SYS. 就找不到对象,不是权限不存在,而是对象解析失败。
常见错误还包括大小写混淆:虽然包名通常大写,但若建库时用了双引号定义(极少见),就必须严格匹配。不过 UTL_HTTP 这类内置包都是标准大写,查 DBA_TAB_PRIVS 时 TABLE_NAME 列也存为大写,所以统一用大写即可。
- 先确认权限真实存在:
SELECT * FROM DBA_TAB_PRIVS WHERE TABLE_NAME = 'UTL_HTTP' AND GRANTEE = 'PUBLIC' AND PRIVILEGE = 'EXECUTE' - 无结果就别执行 REVOKE,否则报
ORA-01927: cannot revoke privileges you did not grant - 必须以
SYS或具备GRANT ANY OBJECT PRIVILEGE的用户连接执行
撤销后用户还能调用 UTL_FILE 怎么办
撤销权限只影响新会话,已连接会话的权限缓存不会自动刷新。用户当前 session 仍能执行 UTL_FILE.FOPEN,直到断开重连或显式刷新权限(如 ALTER SESSION SET CURRENT_SCHEMA = ... 可能触发重检)。
更隐蔽的问题是:依赖该包的 PL/SQL 对象(过程、函数、包体)不会立刻失效,编译状态仍是 VALID;只有下次重新编译或运行时才会报错,典型如 PLS-00201: identifier 'UTL_FILE.FOPEN' must be declared。
- 查潜在依赖:
SELECT OWNER, NAME, TYPE FROM DBA_DEPENDENCIES WHERE REFERENCED_NAME = 'UTL_FILE' AND REFERENCED_OWNER = 'SYS' - 重点看
TYPE IN ('PROCEDURE', 'FUNCTION', 'PACKAGE BODY'),尤其状态为INVALID的对象 - 不要批量
ALTER ... COMPILE—— 先人工确认是否真需UTL_FILE,能否改用外部表或应用层处理
为什么 revoke DELETE ON emp 不生效
最常被忽略的是 DELETE ANY TABLE 这类系统权限。它优先级高于对象级权限,哪怕你撤了某张表的 DELETE,只要用户有这个系统权限,照样能删。
还要确认权限来源:用户可能是通过角色获得的,比如 HR_ROLE 被授了 DELETE ON EMP,而用户只被授予了 HR_ROLE。此时 REVOKE DELETE ON HR.EMP FROM alice 会报 ORA-01927,因为你没直接授过。
- 查直接受权:
SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE = 'ALICE' AND TABLE_NAME = 'EMP' - 查角色继承:
SELECT ROLE FROM DBA_ROLE_PRIVS WHERE GRANTEE = 'ALICE',再查对应角色的权限 - 若权限来自角色,要么
REVOKE HR_ROLE FROM alice,要么REVOKE DELETE ON HR.EMP FROM HR_ROLE(需有 ADMIN OPTION)
PUBLIC 上的同义词忘了删会怎样
仅撤销 EXECUTE ON SYS.UTL_HTTP 不够。如果 DBA 曾创建过 CREATE PUBLIC SYNONYM UTL_HTTP FOR SYS.UTL_HTTP,用户仍可通过 UTL_HTTP.FOPEN 调用——因为同义词还在,且 PUBLIC 对同义词有默认访问权。
同义词不随权限撤销自动清理,必须单独删:DROP PUBLIC SYNONYM UTL_HTTP。这类操作也需 SYS 或具备 DROP PUBLIC SYNONYM 权限的用户执行。
检查是否存在:SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME = 'UTL_HTTP' AND OWNER = 'PUBLIC'。别漏掉大小写变体,比如 utl_http 或 Utl_Http,Oracle 默认转大写存储,但查询时建议用大写。











