必须直接授予EXECUTE权限,不能通过角色;包权限以包为单位不可细分;过程内访问的对象需单独授权;同义词不改变权限检查对象。
用户调用存储过程报 PLS-00201 或 ORA-00942,八成是因为权限是通过角色间接给的。Oracle 在 AUTHID DEFINER(默认)过程里会忽略角色权限,只认直接授予的 EXECUTE。哪怕你建了个 app_exec_role 并把 EXECUTE ON hr.proc_a 塞进去,再把角色授给用户,调用时照样失败。
正确做法只有这一种:GRANT EXECUTE ON hr.proc_a TO app_user; —— 每个过程都得单独、显式、直接授。
GRANT EXECUTE ON schema.name TO user
dba_tab_privs,确认 grantee = 'APP_USER' 且 privilege = 'EXECUTE',而不是看 dba_role_privs
想只给 hr.emp_pkg.get_dept_info 的执行权?不行。Oracle 不支持对包内成员做对象级授权,语法直接报 ORA-00905。包是权限最小单位,要么全放行,要么全拒绝。
GRANT EXECUTE ON hr.emp_pkg TO app_user; ✅ 才是合法写法;GRANT EXECUTE ON hr.emp_pkg.get_dept_info TO app_user; ❌ 会报错。
"Emp_Pkg",授权也得写成 GRANT EXECUTE ON hr."Emp_Pkg" TO app_user;
给了 EXECUTE 权限,不代表用户能跑通过程。只要过程里查了 hr.employees,就得再补一句:GRANT SELECT ON hr.employees TO app_user;。否则过程运行到那行就崩,报 ORA-00942,不是过程本身问题,而是权限链断在底层对象上。
hr)必须已拥有这些表权限,且不能是通过角色获得的——定义者权限过程不认角色SELECT ANY TABLE 这类高危系统权限,宁可一条条授,才符合最小权限原则用户建了同义词 CREATE SYNONYM my_proc FOR hr.proc_a;,然后执行 EXEC my_proc —— 看似绕开了 schema,其实没用。Oracle 先解析出真实对象是 hr.proc_a,再检查当前用户对 hr.proc_a 有没有 EXECUTE 权限。同义词只是别名,不改变权限主体。
GRANT EXECUTE ON hr.proc_a TO app_user;