如何识别哪个用户在特定表上执行了更新语句?

时间:2018-07-17 17:48:43

标签: sql oracle oracle12c

这就是我的情况,在这里我想确定谁更新了我的测试表,但我无权访问sys。

有没有使用sys的方法?

create table test
                 (
                  id      number,
                  name    varchar2(32767),
                  age     number
                 );

insert into test values(2,'XYZ',18);
insert into test values(3,'ABC',19);

随机用户更新了测试表

update test set age =20 where id =3;

2 个答案:

答案 0 :(得分:2)

您可以检查v$sqlv$session。下面的查询将帮助您获取会话详细信息。

select * from v$sql a join v$session b 
on a.sql_id = b.sql_id
where upper(b.sql_fulltext) like %UPDATE%your_table_name%;

您可以在下面的链接中查看更多详细信息。

V$SESSION-https://docs.oracle.com/cd/B19306_01/server.102/b14237/dynviews_2088.htm#REFRN30223

V$SQL-https://docs.oracle.com/database/121/REFRN/GUID-2B9340D7-4AA8-4894-94C0-D5990F67BE75.htm#REFRN30246

V$ACTIVE_SESSION_HISTORY https://docs.oracle.com/cd/B19306_01/server.102/b14237/dynviews_1007.htm#REFRN30299

其他帮助链接-Find out the history of SQL queries

但是,建议您将来使用以下步骤进行记录。

  1. 在表的更新前语句上创建触发器。
  2. 插入到日志表中,并增加两个带有值SYS_CONTEXT('USERENV', 'IP_ADDRESS', 15)SYS_CONTEXT('USERENV', 'HOST', 15)的列(IP和HOST)。
  3. 这将提供运行更新的计算机的IP和主机名。

您可以检查以下查询的输出。

select SYS_CONTEXT('USERENV', 'IP_ADDRESS', 15) ipaddr from dual;

select SYS_CONTEXT('USERENV', 'HOST', 15) host_name from dual;

答案 1 :(得分:1)

通常,最好将DB触发器用于DML操作,以记录人员和相关模块信息。在应用程序层 Client Module 信息可能设置为:

dbms_application_info.set_client_info( my_client_name ); 
dbms_application_info.set_module( my_mdl, null );

为表test所应用的DML操作创建一个记录表是适当的:

create table test( col1 int, col2 varchar2(50) .... ); -- <-- assuming test is as this.
create table log_test( col1 int, col2 varchar2(50) ...., col_cl_info varchar2(64),
           col_terminal varchar2(64), col_opr_time date, col_machine varchar2(64), 
           col_dml_type varchar2(1) , col_module varchar2(64) );

然后,您可以创建如下触发器:

create or replace trigger trg_log_test
  before update or insert on test   
  for each row    
declare
  v_cl_info  v$session.client_info%type;
  v_machine  v$session.machine%type;
  v_module   v$session.module%type;
  v_action   v$session.osuser%type;
  v_dml_type varchar2(1);
begin

  select client_info, machine, module
    into v_cl_info, v_machine, v_module
    from v$session
   where audsid = userenv('SESSIONID');


if v_cl_info in ('oracle') then 
 dbms_application_info.read_client_info( v_cl_info ); 
 dbms_application_info.read_module( v_module, v_action ); 
end if; 

if     inserting then 
  v_dml_type := 'I';
elsif  updating then
  v_dml_type := 'U';
end if;  

  insert into log_test( col1, col2, .... ,
         col_cl_info, col_terminal, col_opr_time , col_machine, col_dml_type, col_module )
  values(:new.col1, :new.col2, .........., 
         v_cl_info , userenv('TERMINAL'),sysdate , v_machine , v_dml_type , v_module  );

end;

其中 v $ session sys.v_ $ session 词典视图的公共同义词