Oracle:在过程中从v$session中选择用户名和当前模式与作为独立语句运行相比,是否会改变结果

rqqzpn5f  于 2023-08-03  发布在  Oracle
关注(0)|答案(1)|浏览(98)

我正在构建一个过程,在系统登录触发器上触发,以记录会话生存期之外的v$session信息。大多数过程都按照预期工作,但是当我尝试记录刚刚登录的会话的schemaname(即在执行任何命令之前),它返回过程位置的schemaname,而不是登录模式的v$session中的schemaname。代码如下:

CREATE OR REPLACE PROCEDURE DB_AUDIT_LOGON (p_sessionid number)
IS
 
   v_sessionid       number;   
   v_sid             number;   
   v_serialno        number;   
   v_username        VARCHAR2 (128); 
   v_schemaname      VARCHAR2 (128); 
   v_osuser          VARCHAR2 (128); 
   v_machine         VARCHAR2 (64); 
   v_terminal        VARCHAR2 (30); 
   v_program         VARCHAR2 (48); 
   v_logon           DATE; 
   v_clientid        VARCHAR2 (64); 
   v_authid          VARCHAR2 (128); 
   v_authmethod      VARCHAR2 (128);
   v_curruser        VARCHAR2 (128);
   v_proxyuser       VARCHAR2 (128);
   v_authtyp         VARCHAR2 (26);
   v_clientdrv       VARCHAR2 (30);
   v_clientver       VARCHAR2 (40);
  
BEGIN

-- Collection of userenv session variables

v_sessionid := p_sessionid;
v_authid := sys_context('USERENV', 'AUTHENTICATED_IDENTITY');
v_authmethod := sys_context('USERENV', 'AUTHENTICATION_METHOD');
v_curruser := sys_context('USERENV', 'CURRENT_USER');
v_proxyuser := sys_context('USERENV', 'PROXY_USER');

-- Collection of all information from v$session

select 
    sid,
    serial#,
    username,
    schemaname,
    osuser,
    machine,
    terminal,
    program,
    logon_time,
    client_identifier
into 
    v_sid,
    v_serialno,
    v_username,
    v_schemaname,
    v_osuser,
    v_machine,
    v_terminal,
    v_program,
    v_logon,
    v_clientid
from v$session where audsid = v_sessionid;

-- Collection of v$session_connect_info variables

select
    unique(authentication_type)
into
    v_authtyp
from v$session_connect_info
where sid = v_sid and serial# = v_serialno;    
    
select    
    unique(client_driver)
into    
    v_clientdrv
from v$session_connect_info
where sid = v_sid and serial# = v_serialno;

select
    unique(client_version)
into
    v_clientver
from v$session_connect_info
where sid = v_sid and serial# = v_serialno;

-- Insertion of collected session information into 
-- DB_AUDIT_LOG

insert into DB_AUDIT_LOG
(
    sessionid,
    sid,
    serialno,
    username,
    schemaname,
    osuser,
    machine,
    terminal,
    program,
    logon_time,
    client_identifier,
    authenticated_identity,
    authentication_method,
    current_user,
    proxy_user,
    authentication_type,
    client_driver,
    client_version)
values
(
    v_sessionid,
    v_sid,
    v_serialno,
    v_username,
    v_schemaname,
    v_osuser,
    v_machine,
    v_terminal,
    v_program,
    v_logon,
    v_clientid,
    v_authid,
    v_authmethod,
    v_curruser,
    v_proxyuser,
    v_authtyp,
    v_clientdrv,
    v_clientver);

END;
/

字符串
我知道我在代码中有一个缺陷,选择sys_context('userenv','current_user'),因为这将默认为存储过程的模式,但不明白为什么会话中的模式名也会这样做。
我正在运行Oracle 19 C,过程在SYS上,因为我在尝试对过程引用的v_$session和v_$session_connect_info表授予选择权限时遇到了复杂的权限问题。
所以,如果我运行select * from v$session;我直接得到SCHEMA_A的模式名,这就是我所追求的,而在我提供的代码中,结果总是SYS。
有谁能告诉我哪里出了问题,我该如何解决?
谢啦,谢啦
肖恩

gj3fmq9x

gj3fmq9x1#

你没做错什么v$session.schemaname更改为当前运行代码的所有者,因此在过程中,您应该捕获过程所有者而不是初始用户。因此,在这样的审计情况下,这个特定的列没有用。只有当您有从会话外部异步轮询v$session的东西时,它才有用,而系统触发器不是这种情况。
不过,这应该不是问题,因为你可以忽略它,使用v$session.username或其他USERENV选项之一。

相关问题