执行存储过程前必须先授予EXECUTE权限,标准语法为GRANT EXECUTE ON schema.procedure_name TO user_name;不可省略schema,且EXECUTE ANY PROCEDURE属高危权限,应遵循最小权限原则。
执行存储过程前必须先有 EXECUTE 权限
用户无法直接运行其他用户(比如 hr、scott)名下的存储过程,哪怕该过程语法正确、已编译成功,也会报 ora-06550: line x, column y: pls-00201: identifier 'xxx' must be declared 或更底层的 ora-00942: table or view does not exist(常因权限缺失导致解析失败)。根本原因不是代码问题,而是缺少对象级的 execute 权限。
grant execute on procedure_name to user_name 是标准写法
给指定用户授予对某个具体存储过程的执行权,必须用完整对象名(含 schema),且不能省略 ON 关键字:
-
GRANT EXECUTE ON hr.get_employee_info TO scott;✅ 正确:显式指定 schema 和过程名 -
GRANT EXECUTE ON get_employee_info TO scott;❌ 错误:Oracle 不会自动补 schema,报ORA-00942 -
GRANT EXECUTE ON hr."Get_Employee_Info" TO scott;⚠️ 注意大小写:若过程名建时用了双引号且含大小写,授权也必须严格匹配 - 过程名不存在或拼写错误时,语句仍能执行成功(Oracle 不校验对象是否存在),但后续
EXEC会失败
EXECUTE ANY PROCEDURE 权限要慎用
该系统权限允许用户执行数据库中任意 schema 下的任意存储过程,等价于“全局执行开关”:
-
GRANT EXECUTE ANY PROCEDURE TO app_user;—— 授予后,app_user可以EXEC hr.payroll_calc();、EXEC sys.dbms_stats.gather_table_stats(...); - 它不隐含对过程内访问的表/视图的读写权限;如果过程里查了
hr.employees,还需单独GRANT SELECT ON hr.employees TO app_user; - 生产环境避免直接授予,优先走最小权限原则:按需授权具体过程,而非开放“any”
- 可通过
SELECT * FROM dba_sys_privs WHERE privilege = 'EXECUTE ANY PROCEDURE';快速审计谁拥有该高危权限
权限生效不需要重新连接,但要注意同义词和调用方式
授权后用户无需重连数据库,但以下细节容易踩坑:
- 若用户通过同义词调用,如
CREATE SYNONYM my_proc FOR hr.proc_a;,则需对同义词所属 schema(这里是当前用户)有EXECUTE权限,而不是对原过程授权 —— 实际上是同义词解析后才检查底层对象权限 - 包中的过程需授权整个包:
GRANT EXECUTE ON hr.emp_pkg TO scott;,不能只授包内某个过程 - 函数和过程权限语法一致,但函数可在 SQL 语句中直接调用(如
SELECT hr.get_dept_name(10) FROM DUAL;),此时还额外要求用户有SELECT权限(因为 SQL 引擎会做权限合并检查) - 使用
DBMS_SCHEDULER调用过程时,job 所在用户必须同时拥有EXECUTE权限和过程内涉及的所有对象权限,否则 job 运行时报错且无明确提示
权限链不会自动传递。即使 A 授予 B 执行权限,B 也不能再转授给 C,除非 A 显式加 WITH GRANT OPTION —— 但 Oracle 对 EXECUTE 对象权限不支持该子句,所以无法二次授权。


















