必须显式授予execute权限且对象名须带schema,否则调用报pls-00201或ora-00942;包内过程需授整个包,同义词调用仍检查原对象权限,角色间接授权在authid definer下无效。

GRANT EXECUTE ON 必须带 schema 名
Oracle 不做隐式 schema 解析,GRANT EXECUTE ON get_employee_info TO scott 会直接报 ORA-00942(表或视图不存在),因为数据库根本找不到不带 owner 的对象名。
正确写法必须显式带上 schema:GRANT EXECUTE ON hr.get_employee_info TO scott。
- 如果过程名建时用了双引号且含大小写(如
"Get_Employee_Info"),授权也必须严格匹配:GRANT EXECUTE ON hr."Get_Employee_Info" TO scott - 权限语句本身不校验对象是否存在——哪怕
hr.get_employee_info根本不存在,GRANT也能执行成功;但后续调用EXEC hr.get_employee_info会直接报错 - 同义词调用不影响权限检查逻辑:用户执行
EXEC my_proc,Oracle 先解析出真实对象是hr.proc_a,再查当前用户对hr.proc_a是否有EXECUTE权限
包内过程不能单独授权,只能授整个包
Oracle 对 package 的权限控制是包级粒度的。试图对包内某个过程单独授权是语法错误。
GRANT EXECUTE ON hr.emp_pkg.get_dept_info TO scott 会报 ORA-00905(缺少关键字)。
- 必须授整个包:
GRANT EXECUTE ON hr.emp_pkg TO scott - 包中函数、过程、类型方法等,权限规则一致,都走包级
GRANT EXECUTE - 即使只用到包里一个函数,也得把整个包的
EXECUTE权限给出去
AUTHID DEFINER 下角色权限无效
默认存储过程是 AUTHID DEFINER(定义者权限),此时用户通过角色获得的权限(比如 SELECT ANY TABLE 或自定义 role)在过程内部不可用。
常见现象:过程里查 hr.employees 报 PLS-00201 或 ORA-00942,但用户自己连上去能正常查——因为过程是以定义者身份运行,不继承调用者的 role。
- 解决方案之一是显式授权:
GRANT SELECT ON hr.employees TO scott(如果过程属于hr,则需由hr授出) - 另一方案是改用
AUTHID CURRENT_USER,让过程以调用者身份执行,此时 role 生效;但注意:调用者必须实际拥有过程里涉及的所有对象权限(比如过程查hr.employees,调用者就得有SELECT ON hr.employees) - 系统权限如
EXECUTE ANY PROCEDURE可绕过对象级限制,但它不赋予过程内部访问表所需的权限——仍要额外授权表级权限
授权后无需重连,但间接授权在 DEFINER 过程中失效
显式授予的 EXECUTE 权限生效即时,用户不用重新连接数据库。
容易被忽略的关键点是:如果把 EXECUTE 权限通过角色(如 app_exec_role)间接授予用户,在 AUTHID DEFINER 存储过程中调用仍会失败。
- 例如:
GRANT app_exec_role TO scott,再让scott调用hr.get_employee_info(AUTHID DEFINER),依然报错 - 必须是直接授权:
GRANT EXECUTE ON hr.get_employee_info TO scott - 角色间接授权只对
AUTHID CURRENT_USER过程有效











