首页 > 解决方案 > oracle 12.2.0.1 中的命名空间 sys_Session_roles 在 sql 查询中工作,但不在 plsql 块内

问题描述

这是我在 oracle 12.2.0.1 中面临的问题。我们最近从 12.1.0.2 迁移。它在那里工作得很好。select SYS_CONTEXT ('SYS_SESSION_ROLES', 'ROLE_XYZ') from dual当作为 sql 查询执行时会给出正确的结果,但在 pl/sql 块中执行时不会给出正确的结果,比如函数。

标签: oraclenamespaces

解决方案


这可能是定义者权利与调用者权利的问题。SQL 和匿名 PL/SQL 块始终以调用者的权限运行,这意味着它们以所有当前启用的角色运行。默认情况下,PL/SQL 对象以定义者的权限运行,这意味着它们仅具有直接授予用户的权限并排除角色。解决方案可能是将您的功能从定义者的权利更改为调用者的权利。

这是SYS_CONTEXT在 SQL 中按预期工作的函数:

select sys_context('SYS_SESSION_ROLES', 'DBA') has_role
from dual;

HAS_ROLE
--------
TRUE

AUTHID DEFINER使用或根本没有子句创建的函数AUTHID将无法识别该角色。

create or replace function has_dba_definers_rights return varchar2 authid definer is
begin
    return SYS_CONTEXT ('SYS_SESSION_ROLES', 'DBA');
end;
/

select has_dba_definers_rights from dual;

HAS_DBA_DEFINERS_RIGHTS
-----------------------
FALSE

通过添加AUTHID CURRENT_USER,该功能现在将识别所有当前启用的角色。

create or replace function has_dba_invokers_rights return varchar2 authid current_user is
begin
    return SYS_CONTEXT ('SYS_SESSION_ROLES', 'DBA');
end;
/

select has_dba_invokers_rights from dual;

HAS_DBA_INVOKERS_RIGHTS
-----------------------
TRUE

从触发器调用时,上面的代码将不起作用。在触发器中以及在从触发器调用的任何对象中,角色始终处于禁用状态。要查找授予用户的角色,在触发器内,您必须查询类似的表DBA_ROLE_PRIVS


推荐阅读