是什么USER()和SYS_CONTEXT( 'USERENV', 'CUR

2019-06-25 10:30发布

在Oracle数据库中,什么是以下之间的区别:

  • 用户()
  • SYS_CONTEXT( 'USERENV', 'CURRENT_USER')
  • SYS_CONTEXT( 'USERENV', 'SESSION_USER')

是什么“时,当前用户”,这些也有可能相关的值是什么?

  • SYS_CONTEXT( 'USERENV', 'CURRENT_SCHEMA')
  • SYS_CONTEXT( 'USERENV', 'AUTHENTICATED_IDENTITY')

我特别感兴趣的是哪些可以改变,有什么可以改变他们,哪些不能改变价值的基础上,连接类型,哪些有不同的价值观,以及哪个(些)是(是)始终使用的模式登录到数据库。

在大多数我的测试值都总是相同的。 运行以下时,以改变“CURRENT_SCHEMA”唯一的例外是:

alter session set current_schema=<SCHEMA>

这样一个错误结果如下:

alter session set current_user=<USER> --even as sys/system, which is good I suppose

因此,有某种围绕这一切的安全/规则。 但是必须是具有SESSION_USER和CURRENT_USER背后的一些原因。 我还假设用户()可能是一个捷径SYS_CONTEXT(“USERENV”,“CURRENT_USER”),但我能找到的关于此事的文档。

Answer 1:

从手动在: http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions184.htm#SQLRF51825

当前用户

但他们的权限是当前活跃的数据库用户的名称。 这可能在会话的持续期间改变,以反映任何活动的定义者权限对象的所有者。 当没有定义者权限对象是活动的,CURRENT_USER返回相同的值SESSION_USER。 当在视图定义的体直接使用,它返回被执行正在使用该视图光标所述用户; 它不尊重游标中使用作为定义者权利的意见。

SESSION_USER

在登录数据库的用户名。 对于企业用户来说,将返回架构。 对于其他用户,返回数据库的用户名。 这个值也保持整个会话的持续时间相同。

因此, 特别是当在CURRENT_USER存储过程或功能用于SESSION_USER和CURRENT_USER之间的差。

我不得不承认,我不知道这个词的“企业用户”是指虽然。

BTW:还有第三个:

SESSION_USERID

在登录数据库用户的标识符。



Answer 2:

sys_context('USERENV', 'CURRENT_SCHEMA') -当前正在使用的和你已经找到了可以改变的模式alter session

sys_context('USERENV', 'SESSION_USER') -这是在创建会话期间用于认证,并且不能被改变的用户

sys_context('USERENV', 'CURRENT_USER') - (至少根据很像“SESSION_USER”弃用10克文档 )
(根据@ a_horse_with_no_name的答案,他给了参考editted 11克文档 )

sys_context('USERENV', 'AUTHENTICATED_IDENTITY') -用于认证身份,取决于“AUTHENTICATION_METHOD”。
从文档 :

  • Kerberos身份验证企业用户:Kerberos主体名称
  • Kerberos的认证的外部用户:Kerberos主体名; 相同的架构名称
  • SSL认证的企业用户:DN中的用户的PKI证书
  • 用户的PKI证书的DN:SSL验证的外部用户
  • 密码验证的企业用户:昵称; 相同的登录名
  • 密码认证的数据库用户:数据库用户名; 相同的架构名称
  • OS验证的外部用户:外部操作系统用户名
  • 半径/ DCE验证的外部用户:方案名称
  • 代理与DN:客户端的Oracle互联网目录DN
  • 代理与证书:客户端的证书DN
  • 代理帐号:如果客户是本地数据库用户数据库用户名; 绰号如果客户是企业用户。
  • SYSDBA / SYSOPER使用口令文件:登录名
  • SYSDBA / SYSOPER使用OS认证:操作系统的用户名

user pseudo column -我不知道,根据文档我倒是觉得它像CURRENT_SCHEMA ,但显然它像CURRENT_USER



Answer 3:

CURRENT_SCHEMA是,如果你的名字对象,而无需指定它的主人将要承担的架构。 举例来说,如果我的CURRENT_SCHEMASCOTT ,则SELECT * FROM EMP相同SELECT * FROM SCOTT.EMP 。 默认情况下,当我第一次连接到Oracle中, CURRENT_SCHEMA是一样的CURRENT_USER。

但是,如果我连为SCOTT ,我可以发出ALTER SESSION SET CURRENT_SCHEMA=JOE ,然后当我做SELECT * FROM EMP ,它被解释为JOE.EMP而非SCOTT.EMP 。 当然,如果我没有SELECT的特权JOE.EMP ,或JOE没有名为对象EMP ,该SELECT将失败。



Answer 4:

存在使用时需要考虑的一个重要的注意USER的PL / SQL函数。 正如我在本博客中记录 , STANDARD.USER()的实现如下:

function USER return varchar2 is
c varchar2(255);
begin
    select user into c from sys.dual;
    return c;
end;

因此,它委托给评估user在SQL引擎,这将导致一个隐藏的PL / SQL到SQL上下文切换。 如果你这样做太频繁,例如从一个触发器中,然后可以变成是在生产系统中很伤人。 尽量避免调用USER()从PL / SQL,并使用sys_context('USERENV', 'SESSION_USER')来代替。



Answer 5:

也有用户使用SYS_CONTEXT之间的性能差异

declare 
  v_result varchar2(100);
begin
  for i in 1..1000000 loop
  v_result := sys_context('userenv','session_user');
  end loop;
end;
/

-- 2.5s

declare 
  v_result varchar2(100);
begin
  for i in 1..1000000 loop
  v_result := user;
  end loop;
end;
/ 

-- 47s

另请参阅https://svenweller.wordpress.com/2016/02/24/sequence-and-audit-columns-with-apex-5-and-12c/和http://www.grassroots-oracle.com/2019 /01/oracle-user-vs-sys-context.html



文章来源: What is the difference between USER() and SYS_CONTEXT('USERENV','CURRENT_USER')?