追踪数据操作者的触发器
在做生产管理系统中,常常会遇到某些表的数据被莫名其妙的修改或删除了,但是很难定位出是哪个用户、哪个过程修改的。
如果要想找出是哪个用户,哪台电脑,甚至是通过什么程序来操作数据的,可以通过SYS_CONTEXT函数 或者通过 系统试图v$session 来查看操作数据的用户信息并通过事件(Event:增删改)触发器来记录Session信息。
1. 使用SYS_CONTEXT函数
SYS_CONTEXT函数用来记录连接的session信息,经常用于触发器中,记录客户端的连接信息(比如IP)。 通过SYS_CONTEXT函数可以取用户session的部分信息,但是客户端程序名不能取得。通过查询试图v$session可以取得客户端用户的程序名。 关于详细SYS_CONTEXT函数介绍,请Google之.
---取用户名:
select USER from dual;
select SYS_CONTEXT('USERENV','SESSION_USER') from dual;
select SYS_CONTEXT('USERENV','CURRENT_USER') from dual;
select SYS_CONTEXT('USERENV','HOST') from dual; -- 取机器名
select SYS_CONTEXT('USERENV', 'IP_ADDRESS') from dual; -- IP地址
2. 使用系统视图 v$session
select
V.USERNAME as 用户名,
V.PROGRAM as 程序名,
V.MACHINE as 机器名,
SYS_CONTEXT('USERENV', 'IP_ADDRESS') as IP地址
from v$session V
where V.audsid = userenv('sessionid');
说明:因为视图V_$SESSION为系统用户sys的视图,其他用户想在触发器中使用该系统视图,必须要SYS给与显示授权。
有关Oracle显示授权请看《Oracle 对象的授权》
要将该系统视图显示授权给触发器创建者,首先要以sys as dba登录,给要创建触发器的用户授予select权限。语句如下:
grant select on V_$SESSION to user1;
3. 通过触发器记录用户操作的例子:
该触发器是记录删除某数据的用户信息
create or replace trigger TRG_LOG_DEL
after delete on T_DATA
REFERENCING NEW AS NEW OLD AS OLD
for each row
declare
vUserName VARCHAR2(50); -- 连接数据库的账号
vProgram VARCHAR2(100); -- 程序
vMachine VARCHAR2(100); -- 机器名
vIp VARCHAR2(100); -- IP地址
begin
if :OLD.STATE='有效数据'then -- 某条件
select V.USERNAME, -- 连接数据库的账号
V.PROGRAM, -- 程序
V.MACHINE, -- 机器名
SYS_CONTEXT('USERENV', 'IP_ADDRESS') -- SYS_CONTEXT函数获得IP地址
into vUserName, vProgram, vMachine, vIp
from v$session V
where v.audsid = userenv('sessionid'); --userenv函数
-- 将删除记录的用户信息和数据记录到表 T_LOG
insert into T_LOG
(日期,
用户,
机器名,
IP地址,
程序名,
被删记录Field1,
被删记录Field2,
....
)
values
(SYSDATE,
vUserName,
vMachine,
vIp,
vProgram,
:OLD.被删记录Field1,
:OLD.被删记录Field2,
....
);
end if;
end TRG_LOG_DEL;
本文结束