在Oracle中,是否有一种方法可以从gv$session获得关于当前会话的信息?

8

有没有办法在 Oracle 的 GV$SESSION 视图中唯一标识当前会话?

我遇到了一个问题,在 Oracle RAC 配置下,以下查询可能会返回多行:

SELECT SID, SERIAL#
FROM GV$SESSION
WHERE AUDSID = Sys_Context('USERENV', 'SESSIONID')
   AND SID = Sys_Context('USERENV', 'SID');

使用V$MYSTAT也不是一个选项,因为当前会话可能无法访问V$MYSTAT(例如当统计信息被禁用时)。

4个回答

12

试试这个:

SELECT SID, SERIAL#
FROM V$SESSION
WHERE AUDSID = Sys_Context('USERENV', 'SESSIONID');

如果您对当前会话感兴趣,那么当前会话必须在本地实例上(根据定义),因此请使用 V$SESSION 而不是 GV$SESSION。此外,您只需要 AUDSID 来唯一标识您的会话。

如果您有一些特殊原因 非常需要 使用 GV$SESSION (无法想象为什么会是这样),则可以改为以下方式:

SELECT SID, SERIAL#
    FROM GV$SESSION
    WHERE AUDSID = Sys_Context('USERENV', 'SESSIONID')
      AND INST_ID = USERENV('Instance');

此外,获取当前会话的SID的另一种方法是:

select sid from v$mystat where rownum=1;

希望这能有所帮助。

很遗憾,在我的情况下,这两个选项都不能使用(我在问题中明确提到了这一点)。在Oracle RAC的情况下,AUDSID加上SID不是唯一的(只有SID和SERIAL#的组合是唯一的),而且由于统计信息被关闭,V$MYSTAT也无法使用。 - Volodymyr Frolov
1
我错过了关于V$MYSTAT的注释,很抱歉。顺便说一句,我不认为这是真的。我没有测试过,但我怀疑V$MYSTAT始终存在。但我没有看到任何关于不能使用V$SESSION而必须使用GV$SESSION的说明。但是,如果由于某种疯狂的原因您真的无法使用V$SESSION,则使用我上面提供的查询,但将其更改回GV$,然后添加一个附加谓词“and inst_id = userenv('Instance')”。这是Oracle在V$视图定义中使用的相同谓词。 - Mark J. Bobak
正如我之前所说,当仅通过AUDSID或者AUDSID加上SID的组合进行过滤时,在Oracle RAC配置中,V$SESSION和GV$SESSION都可能返回多行结果。AUDSID可能不是唯一的。只有SID加上SERIAL#的组合是唯一的,但是如何获取当前会话的SERIAL#呢? - Volodymyr Frolov
但是 inst_id = userenv('Instance') 可能会奏效。您能否将其作为单独的答案添加?如果它有效,我会测试并标记为正确答案。 - Volodymyr Frolov
我已经编辑了上面的答案,因为当我想要添加一个新答案时,系统强烈鼓励我编辑和改进现有的答案,而不是添加一个新答案。 - Mark J. Bobak
从双重选择用户将无法运行。 - user762641

1

加入gv$sessionv$mystat :)

 SELECT SID, SERIAL#,inst_id
  FROM GV$SESSION
 WHERE sid=(select sid from v$mystat where rownum=1); 

0

使用V$SESSION而非GV$SESSION

SELECT SID, SERIAL#
FROM V$SESSION
WHERE SID = Sys_Context('USERENV', 'SID');

在 RAC 安装的情况下,V$SESSION 无法产生唯一的 SIDSERIAL# - Volodymyr Frolov
@VolodymyrFrolov 反过来。GV$SESSION给出每个节点的所有会话,而SID在该视图中可能不是唯一的。V$SESSION仅提供当前节点的会话,并且在该上下文中SID是唯一的,因此如果您从该视图查询自己的会话ID(Sys_Context('USERENV', 'SID')),则将获取您的会话,而不是意外地获取其他人的具有相同SID的会话。 - GolezTrol
1
请参阅RAC V$ vs GV$ views。话虽如此,我不确定为什么在Mark J. Bobak添加了他的回答三年后,我才添加这个回答,因为它包含相同的信息和更多信息。 - GolezTrol

0
尝试这个(需要访问v $ session和v $ sql视图)-
select /*My Sess*/ 'My Sess Text = hello world @ '||systimestamp SID_SR_TXT from dual
union
select 'SID = '||sid||' Serial# = '||serial# SID_SR_TXT  from v$session where sql_id in 
(select sql_id from v$sql where sql_text like '% My Sess %');

2
如果有其他会话试图以相同的方式查找自己,这种方法就行不通了。 "My Sess" 必须被替换为某个独特的标识符。 - Volodymyr Frolov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接