我正在构建一个过程,在系统登录触发器上触发,以记录会话生存期之外的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。
有谁能告诉我哪里出了问题,我该如何解决?
谢啦,谢啦
肖恩
1条答案
按热度按时间gj3fmq9x1#
你没做错什么
v$session.schemaname
更改为当前运行代码的所有者,因此在过程中,您应该捕获过程所有者而不是初始用户。因此,在这样的审计情况下,这个特定的列没有用。只有当您有从会话外部异步轮询v$session
的东西时,它才有用,而系统触发器不是这种情况。不过,这应该不是问题,因为你可以忽略它,使用
v$session.username
或其他USERENV
选项之一。