在Oracle数据库中,以下内容之间存在以下差异:
这些也可能是“当前用户”的相关值吗?
我特别感兴趣的是哪些可以更改,哪些可以更改它们,哪些不能更改值,哪些具有基于连接类型的不同值,以及哪些(始终)是用于的模式登录数据库。
在我的大部分测试中,值始终相同。唯一的例外是运行以下内容以更改'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背后一定有一些原因。我还假设user()可以是sys_context的快捷方式('USERENV','CURRENT_USER'),但我找不到有关此问题的文档。
答案 0 :(得分:15)
来自手册:http://docs.oracle.com/cd/E11882_01/server.112/e26088/functions184.htm#SQLRF51825
其权限当前处于活动状态的数据库用户的名称。这可能会在会话期间发生变化,以反映任何活动定义者权限对象的所有者。当没有定义者的权限对象处于活动状态时,CURRENT_USER返回与SESSION_USER相同的值。当直接在视图定义的主体中使用时,这将返回正在执行使用视图的游标的用户;它不会将游标中使用的视图视为定义者的权利。
登录时数据库用户的名称。对于企业用户,返回架构。对于其他用户,返回数据库用户名。该值在整个会话期间保持不变。
因此是 SESSION_USER和CURRENT_USER之间的区别,尤其是在存储过程或函数中使用CURRENT_USER时。
我不得不承认我不知道“企业用户”这个词的意思。
顺便问一下:还有第三个:登录时数据库用户的标识符。
答案 1 :(得分:3)
sys_context('USERENV', 'CURRENT_SCHEMA')
- 可以使用alter session
sys_context('USERENV', 'SESSION_USER')
- 在创建会话期间用于身份验证且无法更改的用户
sys_context('USERENV', 'CURRENT_USER')
- 非常类似于“session_user”已弃用(至少根据10g documentation)
(根据@ a_horse_with_no_name的答案以及他给11g docs的参考文件进行编辑)
sys_context('USERENV', 'AUTHENTICATED_IDENTITY')
- 用于身份验证的身份取决于“AUTHENTICATION_METHOD”。
来自documentation:
- 经过Kerberos身份验证的企业用户:kerberos主要名称
- Kerberos认证的外部用户:kerberos主要名称;相同 作为模式名称
- 经过SSL身份验证的企业用户:中的DN 用户的PKI证书
- SSL认证的外部用户:中的DN 用户的PKI证书
- 经过密码验证的企业用户: 昵称;与登录名相同
- 经过密码验证的数据库用户: 数据库用户名;与架构名称相同
- OS-认证 外部用户:外部操作系统用户名
- Radius / DCE认证的外部用户:架构名称
- 使用DN的代理 :客户端的Oracle Internet Directory DN
- 证书代理: 客户的证书DN
- 使用用户名的代理:数据库用户名 如果客户端是本地数据库用户;昵称,如果客户是一个 企业用户。
- SYSDBA / SYSOPER使用密码文件:登录名
- 使用OS身份验证的SYSDBA / SYSOPER:操作系统用户名
user pseudo column
- 我不确定,根据文档,我认为它就像CURRENT_SCHEMA
,但显然它就像CURRENT_USER
答案 2 :(得分:1)
CURRENT_SCHEMA
是在未指定对象的情况下命名对象时将采用的架构。例如,如果我的CURRENT_SCHEMA
为SCOTT
,则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
会失败
答案 3 :(得分:1)
使用PL / SQL中的USER
函数时,有一个重要注意事项要考虑。由于我拥有documented in this blog post,STANDARD.USER()
的实现方式如下:
function USER return varchar2 is
c varchar2(255);
begin
select user into c from sys.dual;
return c;
end;
因此,它委派了对SQL引擎中的user
进行评估,这导致了从PL / SQL到SQL上下文的隐藏切换。如果您经常这样做,例如从触发器之内开始,那么在生产系统中可能会造成相当大的伤害。尝试避免从PL / SQL调用USER()
,而改用sys_context('USERENV', 'SESSION_USER')
。
答案 4 :(得分:0)
USER和使用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