authid current_user 是切换权限验证主体的开关,使存储过程等以调用者身份解析对象并校验权限,而非默认的定义者身份;适用于多租户、动态访问等场景,但需确保调用者具备对应对象权限及系统权限。

直接说结论:AUTHID CURRENT_USER 不是“管理权限”的工具,而是切换权限验证主体的开关——它让存储过程、函数或包体在执行时改用调用者(CURRENT_USER)的身份查权限,而不是默认的定义者(创建者)身份。这在多租户、分用户数据隔离或动态对象访问场景中是刚需,但用错会立刻报 ORA-00942 或 ORA-01031。
为什么默认的定义者权限在12c里经常不够用
Oracle 12c 默认仍是 AUTHID DEFINER,即过程以创建者身份运行。这意味着:
- 即使调用者有
DBA角色,过程内部也无法使用该角色的权限(role 在定义者权限下被忽略) - 过程里写的
INSERT INTO my_table,始终指向定义者 schema 下的my_table,调用者无法自动切到自己 schema 的同名表 - 若过程要动态建表(如临时工作表)、调用
UTL_HTTP或访问DBA_*视图,而定义者没被显式授权,就会失败
加了 AUTHID CURRENT_USER 后,SQL 解析和权限检查怎么变
关键变化在两处:对象解析路径 + 权限校验上下文。
- 未加
AUTHID CURRENT_USER:语句SELECT * FROM orders被解析为DEFINER_SCHEMA.orders;权限检查基于定义者已有的显式对象权限 - 加了
AUTHID CURRENT_USER:同一语句被解析为CURRENT_SCHEMA.orders(即当前 session 的CURRENT_SCHEMA,可通过ALTER SESSION SET CURRENT_SCHEMA = xxx切换);权限检查走调用者当前拥有的全部权限,包括 role 授予的权限 - 注意:如果调用者没在自己的 schema 下建
orders表,哪怕定义者有,也会报ORA-00942: table or view does not exist
常见踩坑点:不是加了就万事大吉
加 AUTHID CURRENT_USER 是起点,不是终点。以下问题高频出现:
- 过程里硬编码了
schema.table(如hr.employees),但调用者没有hr.employees的 SELECT 权限 → 报ORA-01031: insufficient privileges - 过程内用
EXECUTE IMMEDIATE动态建表,但调用者没被授予CREATE TABLE系统权限 → 即使有RESOURCE角色也不行(role 在定义者权限下无效,但这里已是调用者权限,所以必须显式授CREATE TABLE) - 包体(package body)和包头(package spec)权限不一致:只在包头上加
AUTHID CURRENT_USER不生效,必须在包体上也声明(Oracle 要求两者 authid 一致,否则编译报错) - 12c 中启用 PDB 时,
CURRENT_USER指的是当前 PDB 内的用户,跨 PDB 访问需额外配置服务名和连接凭证,不能靠 authid 解决
一个最小可验证示例
假设用户 app_user 创建过程,希望 report_user 调用时操作自己 schema 下的 sales_summary 表:
CREATE OR REPLACE PROCEDURE app_user.gen_report AUTHID CURRENT_USER AS
BEGIN
INSERT INTO sales_summary (period, amount)
SELECT TO_CHAR(SYSDATE, 'YYYY-MM'), SUM(value)
FROM transactions;
COMMIT;
END;
然后确保:GRANT EXECUTE ON app_user.gen_report TO report_user;,且 report_user 自己 schema 下存在 sales_summary 表,并有 INSERT 权限。缺任何一环都会失败。
最易被忽略的是:这个过程对 report_user 是否真的有用,取决于 report_user 是否拥有 transactions 表的 SELECT 权限——因为 FROM transactions 也在调用者 schema 下解析,不是 app_user.transactions。











