revoke execute on procedure_name from username 语法不足够,必须显式指定schema前缀(如hr.proc_name),若过程名含双引号则大小写敏感;若权限通过角色授予,直接revoke会报ora-01927,需先查角色来源再撤角色或角色权限。
revoke execute on procedure_name from username 语法是否足够
不够。直接写 revoke execute on proc1 from scott 可能失败,常见报错是 ora-00942: table or view does not exist——这其实不是对象不存在,而是你没指定 schema。oracle 要求存储过程名必须带所有者前缀,比如 hr.get_employee_info,不能只写 get_employee_info。
正确写法必须显式带上 owner:
REVOKE EXECUTE ON hr.get_employee_info FROM scott;
- 如果存储过程在当前用户(如
scott)自己 schema 下,也要写成scott.proc_name,不能省略 - 大小写敏感:若创建时用了双引号(
CREATE OR REPLACE PROCEDURE "MyProc"),回收时也得用"MyProc" -
EXECUTE是唯一合法的对象权限类型,不能写SELECT或UPDATE——对过程无效
用户是通过角色获得的 EXECUTE 权限,revoke 会失败吗
会,而且报错通常是 ORA-01927: cannot revoke privileges you did not grant。因为 REVOKE EXECUTE ON ... FROM user 只能撤掉“直接授予”的权限;如果 scott 是通过角色 app_developer 得到该权限,那这条语句根本找不到可撤的直授记录。
查来源分两步:
SELECT granted_role FROM dba_role_privs WHERE grantee = 'SCOTT';
SELECT * FROM role_tab_privs WHERE role = 'APP_DEVELOPER' AND privilege = 'EXECUTE' AND table_name = 'GET_EMPLOYEE_INFO';
- 确认后,要么撤角色:
REVOKE app_developer FROM scott - 要么从角色本身撤权限(需你有
ADMIN OPTION):REVOKE EXECUTE ON hr.get_employee_info FROM app_developer
回收后,调用过程时报 ORA-06550 / PLS-00201 怎么办
这是典型权限失效表现,但要注意:错误发生在运行时,不是编译时。即使过程本身还能编译成功(比如它只依赖自身 schema 内对象),只要执行时需要访问被撤权的外部过程,就会炸。
验证方式很简单:
SELECT * FROM dba_tab_privs WHERE grantee = 'SCOTT' AND table_name = 'GET_EMPLOYEE_INFO' AND privilege = 'EXECUTE';
- 结果为空 → 权限确实没了
- 结果有记录但
OWNER不是HR→ 可能是同名过程在别的 schema,你撤错了目标 - 用户正在用 synonym 调用 → 检查 synonym 定义:
SELECT table_owner, table_name FROM all_synonyms WHERE synonym_name = 'GET_EMPLOYEE_INFO' AND owner = 'SCOTT'
带包的存储过程(package)怎么回收 EXECUTE 权限
和单个 procedure 一样,但对象名是 package 名,不是里面某个 procedure 的名字。例如要撤 hr.pkg_emp.get_info 的调用权,你撤的是整个包:
REVOKE EXECUTE ON hr.pkg_emp FROM scott;
- 不能写
REVOKE EXECUTE ON hr.pkg_emp.get_info FROM scott——语法错误,Oracle 不支持粒度到包内子程序 - 撤包权限不影响包体编译,但运行时任何对包内任意过程/函数的调用都会失败
- 如果用户已有
EXECUTE ANY PROCEDURE系统权限,对象级REVOKE无效 ——得先查dba_sys_privs并同步回收系统权限
实际操作中最容易忽略的一点:权限回收不触发依赖对象自动重编译。如果用户 scott 自己有个调用了 hr.get_employee_info 的存储过程,回收后那个过程状态会变成 INVALID,但 Oracle 不报错也不提醒——直到下次执行才暴露问题。











