必须显式授予 EXECUTE 权限且对象名须带 schema,否则调用报 PLS-00201 或 ORA-00942;包内过程需授整个包,同义词调用仍检查原对象权限,角色间接授权在 AUTHID DEFINER 下无效。
必须显式授予 execute 权限,且对象名必须带 schema;否则调用时大概率报 pls-00201 或 ora-00942。
GRANT EXECUTE ON 后面必须写全 schema.procedure_name
Oracle 不做隐式 schema 解析,GRANT EXECUTE ON get_employee_info TO scott 会直接失败(报 ORA-00942),因为数据库根本找不到不带 schema 的对象名。
- ✅ 正确写法:
GRANT EXECUTE ON hr.get_employee_info TO scott; - ❌ 错误写法:
GRANT EXECUTE ON 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会直接报错
包里的过程不能单独授权,必须授整个包
Oracle 对 package 的权限控制是包级粒度的。对包内某个过程或函数单独写 GRANT EXECUTE ON hr.emp_pkg.get_dept_info TO scott 是语法错误,数据库不支持这种写法。
- ✅ 正确做法:
GRANT EXECUTE ON hr.emp_pkg TO scott; - ❌ 无效尝试:
GRANT EXECUTE ON hr.emp_pkg.get_dept_info TO scott;(报 ORA-00905) - 包中函数和过程权限规则一致,都走
GRANT EXECUTE ON package_name
通过同义词调用时,权限检查发生在解析后
如果用户用 CREATE SYNONYM my_proc FOR hr.proc_a; 创建了同义词,那么调用 EXEC my_proc 时,Oracle 先解析出真实对象是 hr.proc_a,再检查当前用户对 hr.proc_a 是否有 EXECUTE 权限。
- ✅ 正确做法:对原对象授权,
GRANT EXECUTE ON hr.proc_a TO scott; - ❌ 错误理解:以为只要给同义词所在 schema 授权就行;同义词本身没有独立的
EXECUTE权限类型 - 注意:
EXECUTE ANY PROCEDURE是系统权限,绕过所有对象级限制,但它不赋予过程内部访问表所需的权限——比如过程里查hr.employees,还得额外GRANT SELECT ON hr.employees TO scott;
权限生效不需要重连,但角色授予的 EXECUTE 无效
授权后用户无需重新连接数据库,但容易忽略一个关键点:如果把 EXECUTE 权限通过角色(如 app_exec_role)间接授予用户,在 AUTHID DEFINER 过程中调用会失败,报 PLS-00201 或 ORA-00942。
- ❌ 错误链路:
GRANT EXECUTE ON APP_OWNER.p_check_balance TO app_exec_role;→GRANT app_exec_role TO app_user; - ✅ 唯一可靠方式:
GRANT EXECUTE ON APP_OWNER.p_check_balance TO app_user;(逐个、直接授予) - 若过程数量多,可用脚本生成授权语句,但不能跳过“直接授予”这步
最常被忽略的是:权限语句成功执行 ≠ 过程能跑通。真正卡住的地方往往在定义者权限模型下缺失对底层对象的直授权限,或者误信角色能传递 EXECUTE——这两点一旦出错,错误信息反而指向对象不存在,容易误导排查方向。











