Oracle 审计 table 使用触发器
Oracle Audit table using trigger
我需要在 Oracle 11g 中创建一个触发器来审计 table。我有一个 table 有 16 列需要审计。
对于 table 中的每个新插入,我需要在审计 table 中为插入的每一列添加一个条目,即在这种情况下,将在审计 table 中插入 16 行.
对于每次更新,假设我更新了第 1 列和第 2 列,那么它会在审计中创建两条记录,其中包含旧值和新值。审计结构 table 将是:
id
mod_col_name
OLD VALUE
NEW VALUE
upd_time
mod_user_id
我的做法:
create or replace trigger my_trigger
after update or insert on temp12
for each row
declare
TYPE tab_col_nt IS table of varchar2(30);
v_tab_col_nt tab_col_nt;
begin
v_tab_col_nt := tab_col_nt('id','name','salary'); --in example i have given only 3 column name
for r in v_tab_col_nt.first..v_tab_col_nt.last
loop
if updating(v_tab_col_nt(r)) then
insert into audit_table values (
id_seq.nextval, v_tab_col_nt(r), :old.v_tab_col_nt(r),
:new.v_tab_col_nt(r), sysdate, user
); --here :old & :new syntex is not working
end if;
if inserting then
insert into audit_table values (
id_seq.nextval, v_tab_col_nt(r), null,
:new.v_tab_col_nt(r), sysdate, user);
end if;
end loop;
end;
我的顾虑:
这里 :old.v_tab_col_nt(r), :new.v_tab_col_nt(r) 不工作
如何跟踪用户登录 GUI 的用户 ID(dot net 是前端)。
我想动态写入这个触发器。
:old.v_tab_col_nt(r)
和 :new.v_tab_col_nt(r)
不起作用的原因是因为 :old
和 :new
仅供新旧参考(呃!...) table 中受影响的列中的值,而不是触发器内声明的用户定义类型。
您实际查找的值是::old.<name of column1>
,或:new.<name of column1>
。
因此,根据您的要求,您的触发器必须如下所示:
create or replace trigger my_trigger
after insert or update on temp12
for each row
referencing old as old new as new
begin
/*When-Insert block. 1 record for each column in audit*/
if (INSERTING) then --
insert into audit_table values (id_seq.nextval, '<name of column1>', :old.<name of column1>, :new.<name of column1>, sysdate, user);
insert into audit_table values (id_seq.nextval, '<name of column2>', :old.<name of column2>, :new.<name of column2>, sysdate, user);
insert into audit_table values (id_seq.nextval, '<name of column3>', :old.<name of column3>, :new.<name of column3>, sysdate, user);
.
. --(same for every column)
.
insert into audit_table values (id_seq.nextval, '<name of column16>', :old.<name of column16>, :new.<name of column16>, sysdate, user);
end if;
/*end of When-Insert block*/
/*When-Update block. A new record in audit just for the updated column(s) */
if (UPDATING ( '<name of column1>' )) then --col 1
insert into audit_table values (id_seq.nextval, '<name of column1>', :old.<name of column1>, :new.<name of column1>, sysdate, user);
end if;
if (UPDATING ( '<name of column2>' )) then --col 2
insert into audit_table values (id_seq.nextval, '<name of column2>', :old.<name of column2>, :new.<name of column2>, sysdate, user);
end if;
if (UPDATING ( '<name of column3>' )) then --col 3
insert into audit_table values (id_seq.nextval, '<name of column3>', :old.<name of column3>, :new.<name of column3>, sysdate, user);
end if;
.
. --(same for every column)
.
if (UPDATING ( '<name of column16>' )) then --col 16
insert into audit_table values (id_seq.nextval, '<name of column16>', :old.<name of column16>, :new.<name of column16>, sysdate, user);
end if;
/*end of When-Update block*/
end;
现在关于跟踪登录用户进入您的应用程序有两个注意事项:
如果您的整个应用程序在数据库级别实现了所有用户,
这是每个登录个人的 ORACLE 用户,如果是这样,则
每个 PL/SQL 块或执行的 DDL 中的保留字 "USER",将
每次都检索该用户名。
另一方面,如果您的应用程序决定管理用户
他们自己的,通过创建自定义用户控件,那么该值必须
通过参数传递(在命名的 PL/SQL 块的情况下)或
在每个 table 中包含一个 (NOT NULL) 列(至少每个 table
你想监视用户 activity),所以每个 INSERT
语句都是
强制发送该信息,您可以在里面使用 :new.<name of user monitor column>
阅读它
您的触发器代码,或者您可以使用
IF (:new.< name of user monitor column > is null) then raise_application_error(-20001, 'User must be specified').
END IF;
愿原力与你同在
我需要在 Oracle 11g 中创建一个触发器来审计 table。我有一个 table 有 16 列需要审计。
对于 table 中的每个新插入,我需要在审计 table 中为插入的每一列添加一个条目,即在这种情况下,将在审计 table 中插入 16 行.
对于每次更新,假设我更新了第 1 列和第 2 列,那么它会在审计中创建两条记录,其中包含旧值和新值。审计结构 table 将是:
id
mod_col_name
OLD VALUE
NEW VALUE
upd_time
mod_user_id
我的做法:
create or replace trigger my_trigger
after update or insert on temp12
for each row
declare
TYPE tab_col_nt IS table of varchar2(30);
v_tab_col_nt tab_col_nt;
begin
v_tab_col_nt := tab_col_nt('id','name','salary'); --in example i have given only 3 column name
for r in v_tab_col_nt.first..v_tab_col_nt.last
loop
if updating(v_tab_col_nt(r)) then
insert into audit_table values (
id_seq.nextval, v_tab_col_nt(r), :old.v_tab_col_nt(r),
:new.v_tab_col_nt(r), sysdate, user
); --here :old & :new syntex is not working
end if;
if inserting then
insert into audit_table values (
id_seq.nextval, v_tab_col_nt(r), null,
:new.v_tab_col_nt(r), sysdate, user);
end if;
end loop;
end;
我的顾虑:
这里 :old.v_tab_col_nt(r), :new.v_tab_col_nt(r) 不工作
如何跟踪用户登录 GUI 的用户 ID(dot net 是前端)。
我想动态写入这个触发器。
:old.v_tab_col_nt(r)
和 :new.v_tab_col_nt(r)
不起作用的原因是因为 :old
和 :new
仅供新旧参考(呃!...) table 中受影响的列中的值,而不是触发器内声明的用户定义类型。
您实际查找的值是::old.<name of column1>
,或:new.<name of column1>
。
因此,根据您的要求,您的触发器必须如下所示:
create or replace trigger my_trigger
after insert or update on temp12
for each row
referencing old as old new as new
begin
/*When-Insert block. 1 record for each column in audit*/
if (INSERTING) then --
insert into audit_table values (id_seq.nextval, '<name of column1>', :old.<name of column1>, :new.<name of column1>, sysdate, user);
insert into audit_table values (id_seq.nextval, '<name of column2>', :old.<name of column2>, :new.<name of column2>, sysdate, user);
insert into audit_table values (id_seq.nextval, '<name of column3>', :old.<name of column3>, :new.<name of column3>, sysdate, user);
.
. --(same for every column)
.
insert into audit_table values (id_seq.nextval, '<name of column16>', :old.<name of column16>, :new.<name of column16>, sysdate, user);
end if;
/*end of When-Insert block*/
/*When-Update block. A new record in audit just for the updated column(s) */
if (UPDATING ( '<name of column1>' )) then --col 1
insert into audit_table values (id_seq.nextval, '<name of column1>', :old.<name of column1>, :new.<name of column1>, sysdate, user);
end if;
if (UPDATING ( '<name of column2>' )) then --col 2
insert into audit_table values (id_seq.nextval, '<name of column2>', :old.<name of column2>, :new.<name of column2>, sysdate, user);
end if;
if (UPDATING ( '<name of column3>' )) then --col 3
insert into audit_table values (id_seq.nextval, '<name of column3>', :old.<name of column3>, :new.<name of column3>, sysdate, user);
end if;
.
. --(same for every column)
.
if (UPDATING ( '<name of column16>' )) then --col 16
insert into audit_table values (id_seq.nextval, '<name of column16>', :old.<name of column16>, :new.<name of column16>, sysdate, user);
end if;
/*end of When-Update block*/
end;
现在关于跟踪登录用户进入您的应用程序有两个注意事项:
如果您的整个应用程序在数据库级别实现了所有用户, 这是每个登录个人的 ORACLE 用户,如果是这样,则 每个 PL/SQL 块或执行的 DDL 中的保留字 "USER",将 每次都检索该用户名。
另一方面,如果您的应用程序决定管理用户 他们自己的,通过创建自定义用户控件,那么该值必须 通过参数传递(在命名的 PL/SQL 块的情况下)或 在每个 table 中包含一个 (NOT NULL) 列(至少每个 table 你想监视用户 activity),所以每个
INSERT
语句都是 强制发送该信息,您可以在里面使用:new.<name of user monitor column>
阅读它 您的触发器代码,或者您可以使用
IF (:new.< name of user monitor column > is null) then raise_application_error(-20001, 'User must be specified').
END IF;
愿原力与你同在