Oracle中直接执行REVOKE SELECT ON schema.table FROM user无法批量撤销,因不支持通配符且需先确认权限来源:若用户通过角色(如hr_role)间接获得权限,直撤会报ORA-01927;须先查dba_tab_privs确认直授权限,再查dba_role_privs和role_tab_privs追溯角色路径,最后针对性撤销角色或角色内权限。
直接执行 revoke select on schema.table from user 无法批量撤销——oracle 不支持通配符,必须逐表处理。
查清用户到底有没有直接被授予 SELECT 权限
很多情况下用户是通过角色(比如 hr_role)间接获得权限的,REVOKE SELECT ON ... FROM user 会报 ORA-01927: cannot revoke privileges you did not grant。
- 先查用户直接受权:
SELECT owner, table_name, privilege FROM dba_tab_privs WHERE grantee = 'USER_NAME' AND privilege = 'SELECT' - 再查角色路径:
SELECT granted_role FROM dba_role_privs WHERE grantee = 'USER_NAME',然后对每个角色查SELECT * FROM role_tab_privs WHERE role = 'ROLE_NAME' AND privilege = 'SELECT' - 如果权限来自角色,就得
REVOKE hr_role FROM user_name或者REVOKE SELECT ON schema.table FROM hr_role(需你有ADMIN OPTION)
生成并执行批量 REVOKE 脚本(仅对直接受权有效)
确认权限是直接授予后,用以下查询生成语句:
SELECT 'REVOKE SELECT ON ' || owner || '.' || table_name || ' FROM user_name;' FROM dba_tab_privs WHERE grantee = 'USER_NAME' AND owner = 'SCHEMA_NAME' AND privilege = 'SELECT';
注意三点:
- 输出结果要人工检查,排除
SYS、SYSTEM等系统对象 - 若某条语句执行报
ORA-01720: grant option does not exist,说明该表上有视图依赖,得先删视图或加CASCADE CONSTRAINTS -
REVOKE SELECT ON schema.table FROM user_name CASCADE CONSTRAINTS只删基于该权限建的视图定义,不删函数/包里的硬编码引用
为什么 revoke 后用户还能查?重点排查 DELETE ANY TABLE 之外的干扰项
除了常见的 SELECT ANY TABLE,还有几个隐蔽来源容易漏:
-
SELECT_CATALOG_ROLE这个预置角色默认带大量数据字典表的SELECT权限,且能跨 schema 查dba_*视图 - 用户被授予了
public的权限:SELECTonschema.tableTOpublic—— 这时撤个人权限没用,得REVOKE SELECT ON schema.table FROM public - 同义词(synonym)指向其他 schema 的表,而用户对那个目标表有权限 —— 撤本 schema 表权限不影响通过 synonym 访问
真正难的不是写脚本,是厘清权限来源链;Oracle 的权限模型里,“谁授的”比“授了什么”更关键。一旦走错路径,命令执行成功但权限照旧存在。


















