我正在构建一个程序,在系统登录触发器上触发,以记录会话生命周期之外的 v$session 信息。大多数过程完全按照预期工作,但是当我尝试记录刚刚登录的会话的模式名称时(即在其上执行任何命令之前),它返回过程位置的模式名称,而不是登录模式的 v$session 中的模式名称。我的代码如下:
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 19C,该过程位于 SYS 上,因为我在尝试对该过程引用的 v_$session 和 v_$session_connect_info 表授予选择权限时遇到了复杂的权限问题。
所以,如果我运行 select * from v$session;我直接得到了 SCHEMA_A 的模式名,这就是我想要的,而在我提供的代码中,结果始终是 SYS。
任何人都可以告诉我哪里出了问题以及如何解决这个问题吗?
谢谢
肖恩