直接用REVOKE命令即可撤销,但必须由表所有者、SYS、SYSTEM或拥有GRANT ANY OBJECT PRIVILEGE的用户执行,且权限类型、对象名(含schema和大小写)须严格匹配原授权语句;撤销前须先查DBA_TAB_PRIVS确认权限真实存在,否则REVOKE会静默忽略。

直接用 REVOKE 命令即可撤销,但必须由有权限的用户(如表所有者、SYS、SYSTEM 或拥有 GRANT ANY OBJECT PRIVILEGE 的用户)执行,且权限类型和对象范围要严格匹配原授权语句。
撤销前先确认权限是否真实存在
Oracle 不会报错提示“该权限不存在”,而是静默忽略无效的 REVOKE。所以务必先查清目标用户当前实际拥有的对象权限:
- 查某用户对特定表的权限:
SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE = 'USER_NAME' AND TABLE_NAME = 'TABLE_NAME' AND OWNER = 'SCHEMA_NAME'; - 若用普通用户登录,只能查自己被授的权限:
SELECT * FROM USER_TAB_PRIVS WHERE TABLE_NAME = 'TABLE_NAME'; - 注意大小写:Oracle 默认大写对象名,
'my_table'和'MY_TABLE'是不同的
用 REVOKE 撤销指定表的 SELECT/INSERT 等权限
语法严格对应当初 GRANT 的写法,包括 schema 名、权限粒度、大小写:
- 撤销单个权限:
REVOKE SELECT ON SCHEMA_NAME.TABLE_NAME FROM USER_NAME; - 撤销多个权限:
REVOKE INSERT, UPDATE ON SCHEMA_NAME.TABLE_NAME FROM USER_NAME; - 如果原授权用了双引号定义大小写敏感的表名,这里也必须加引号:
REVOKE SELECT ON "MyTable" FROM USER_NAME; - 不能省略 schema:即使当前用户是 owner,
REVOKE SELECT ON TABLE_NAME FROM USER_NAME会报ORA-01749: you may not grant/revoke privileges to/from yourself
带 WITH GRANT OPTION 的权限要特殊处理
如果原授权用了 WITH GRANT OPTION,被授权用户可能已把权限转授给他人。此时仅执行 REVOKE 只收回该用户权限,不会级联撤销下游权限:
- 先查谁被转授了:
SELECT * FROM DBA_TAB_PRIVS WHERE GRANTOR = 'USER_NAME' AND TABLE_NAME = 'TABLE_NAME'; - 要彻底清理,需逐个
REVOKE下游用户的权限 - 若想一次性阻断传播链,可用
REVOKE ... FROM USER_NAME CASCADE CONSTRAINTS(仅适用于某些约束相关权限,不通用);标准对象权限无级联关键字,必须手动清理
常见失败原因和绕过方式
执行 REVOKE 报错时,大概率不是语法问题,而是权限或上下文不满足:
-
ORA-01927: cannot revoke privileges you did not grant:当前用户不是原始授权者,也不是SYS/SYSTEM,也没有GRANT ANY OBJECT PRIVILEGE系统权限 -
ORA-00942: table or view does not exist:schema 名错误、表不存在、或当前用户无权访问DBA_*视图(此时换SYS AS SYSDBA登录再试) - 用户已被锁或过期:
ALTER USER USER_NAME ACCOUNT UNLOCK;和ALTER USER USER_NAME IDENTIFIED BY newpass;可能需前置执行 - 权限来自角色(如
RESOURCE)?REVOKE对象权限无效,得先REVOKE RESOURCE FROM USER_NAME,或改用REVOKE SELECT ON ... FROM ROLE_NAME
真正容易被忽略的是:撤销操作本身不会触发任何日志提示,也不会检查该权限是否正在被会话使用——哪怕用户此刻正连着并查询这张表,REVOKE 仍会成功,下次其会话再执行对应操作时才报 ORA-01031: insufficient privileges。


















