dbms_scheduler任务以job owner身份运行且权限校验基于其直接权限,12c起不再继承session用户权限;result_cache在12c+支持invoker rights函数但缓存键含调用者身份;多租户下权限需显式指定container;19c禁止boolean用于sql上下文。

DBMS_SCHEDULER任务默认以创建者身份运行,但权限检查实际看job owner
12c起,DBMS_SCHEDULER任务不再隐式继承当前session用户的对象权限。任务执行时,Oracle校验的是job owner(即创建该job的用户)对目标对象(如表、过程)的直接权限,而不是调用CREATE_JOB时所在session的用户权限。
常见错误现象:ORA-00942: table or view does not exist 或 ORA-01031: insufficient privileges,即使当前用户能正常执行pkg_clean.upd_stats,job仍失败。
实操建议:
- 确保
job owner显式拥有目标过程所访问的所有表的SELECT/UPDATE等权限(不能只靠角色) - 避免用
GRANT EXECUTE ON pkg_clean TO PUBLIC这类宽泛授权,PUBLIC不参与调度权限解析 - 若需跨schema调用,用
ALTER SESSION SET CURRENT_SCHEMA = target_schema在job_action中包裹逻辑不推荐;应直接授予权限给job owner
RESULT_CACHE在调用者权限(Invoker Rights)函数中12c起才被允许
11g及更早版本中,带AUTHID CURRENT_USER的函数若声明RESULT_CACHE,编译直接报PLS-00999: implementation restriction...。12c解除了该限制,但行为有关键变化:缓存键自动包含当前调用者身份。
这意味着同一函数对USER_ONE和USER_TWO传入相同参数,会生成两个独立缓存条目——安全了,但内存开销翻倍。
实操建议:
- 升级到12c+后,可放心启用
RESULT_CACHE,无需改写逻辑 - 监控
V$RESULT_CACHE_MEMORY,确认缓存未因多租户或大量不同用户调用而膨胀失控 - 若函数仅被单用户高频调用,保留
RESULT_CACHE收益明显;若为公共API,需权衡缓存粒度与内存占用
多租户(CDB/PDB)下权限作用域必须显式声明container子句
12c引入多租户后,权限不再“全局有效”。在CDB根容器中授予的系统权限(如CREATE JOB),默认只对CDB$ROOT生效;PDB中要创建调度任务,必须单独在对应PDB内授予该权限。
常见错误现象:在CDB中执行GRANT CREATE JOB TO c##app_user,然后连入PDB执行DBMS_SCHEDULER.CREATE_JOB,报ORA-01031。
实操建议:
- 连接到目标PDB后,再执行
GRANT CREATE JOB TO app_user(注意:这里是本地用户,不带C##前缀) - 公共用户(
C##xxx)在CDB中授予权限后,需加CONTAINER=ALL才能透传到所有PDB:GRANT CREATE JOB TO c##app_user CONTAINER=ALL - 查权限时别只看
DBA_SYS_PRIVS,要结合CON_ID字段过滤,或用SELECT * FROM CDB_SYS_PRIVS WHERE CON_ID = SYS_CONTEXT('USERENV', 'CON_ID')
BOOLEAN类型不能用于SQL上下文是19c才强制的断裂点
12c仍允许PL/SQL BOOLEAN变量在动态SQL中隐式转为CHAR(如EXECUTE IMMEDIATE 'SELECT * FROM t WHERE flag = :b' USING my_bool),19c彻底禁止,报PLS-00382: expression is of wrong type。
这不属于传统“权限模型”,但直接影响含动态SQL的调度任务能否在19c运行——尤其当job_action是PLSQL_BLOCK且含EXECUTE IMMEDIATE时。
实操建议:
- 所有传入动态SQL的BOOLEAN变量,必须先转为
CHAR(1)或NUMBER(1),例如bool_to_yn(my_flag) - 检查
DBA_SCHEDULER_JOBS中JOB_ACTION字段,搜索EXECUTE IMMEDIATE和BOOLEAN关键词 - 19c迁移前,用
SELECT * FROM all_plsql_object_settings WHERE warning_setting LIKE '%PLS-00382%'扫描存量包体
真正容易被忽略的是:权限问题往往不是“有没有”,而是“在哪一层生效”。CDB/PDB边界、job owner与session user分离、动态SQL的类型隐式转换——三者叠加时,错误信息可能指向完全无关的方向。











