如何比较触发器中的旧值和新值,然后在审计 table 中标记为 insert/update/delete
How to compare old value and new value in triggers and then mark as insert/update/delete in audit table
CREATE TABLE source_det (
det_id number(10) by default IDENTITY
e_id NUMBER(10),
sys_name VARCHAR2(20),
ref_id NUMBER(10),
sys_other VARCHAR2(30)
);
INSERT INTO source_det VALUES(1,11,'SOURCE',992,null);
INSERT INTO source_det VALUES(2,11,'SOURCE',637,null);
INSERT INTO source_det VALUES(3,11,'SOURCE',null,'Manual');
INSERT INTO source_det VALUES(4,11,'TARGET',637,null);
INSERT INTO source_det VALUES(5,12,'TARGET',637,null);
Audit table:
CREATE SEQUENCE audit_tab_sq;
CREATE TABLE audit_tab (
a_id NUMBER(10) default audit_tab_sq.nextval,
l_transaction varchar2(20),--INSERT, UPDATE, DELETE
e_id NUMBER(10),
sys_name VARCHAR2(20),
value_old VARCHAR2(20),
value_new VARCHAR2(20)
);
I need to create a trigger that will get fired whenever there is new event occurred on the main table i.e source_det
我的尝试:
create or replace trigger audit_tab_trg
AFTER INSERT OR DELETE OR UPDATE ON source_det
FOR EACH ROW
BEGIN
--Need to insert records into the audit table whenever there is a new entry
IF inserting THEN
--new ref_id value
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'INSERT',:new.e_id,:new.sys_name,NULL,:new.ref_id);
--new sys_other
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'INSERT',:new.e_id,:new.sys_name,NULL,:new.sys_other);
END IF;
END;
当我将 ref_id
的一条记录插入 table source_Det
然后在审计中 table 我得到两条记录但理想情况下,它应该检查并仅加载新插入的值。
当前输出:
+------+---------------+------+----------+-----------+-----------+
| a_id | l_transaction | e_id | sys_name | value_old | value_new |
+------+---------------+------+----------+-----------+-----------+
| 1 | INSERT | 13 | TARGET | null | 637 |
| 2 | INSERT | 13 | TARGET | null | null |
+------+---------------+------+----------+-----------+-----------+
预期输出:
+------+---------------+------+----------+-----------+-----------+
| a_id | l_transaction | e_id | sys_name | value_old | value_new |
+------+---------------+------+----------+-----------+-----------+
| 1 | INSERT | 13 | TARGET | null | 637 |
+------+---------------+------+----------+-----------+-----------+
基本上,我需要检查两列 ref_id
和 sys_other
。如果只有 ref_id
被用户输入或被用户修改或被用户删除,那么它应该被标记为 inserted/updated/deleted 进入审核 table。
如果只有 sys_other
由用户输入或由用户修改或由用户删除,那么它应该被标记为 inserted/updated/deleted 进入审核 table.
为什么你不听我之前的建议?您真的应该将新的一对 new/old 列添加到审计 table 中,而不是将 所有内容 放入 value_old/value_new 因为 - 因为您不存储信息它代表什么 - 你必须猜测(这就是解决问题的方法)。
顺便说一句,如果您在同一语句中同时修改 REF_ID
和 SYS_OTHER
,您会怎么做?您必须首先检查您做了什么,然后插入(或不插入)一行。太多的代码以获得一点好处。
if :new.ref_id is not null then
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'INSERT',:new.e_id,:new.sys_name,NULL,:new.ref_id);
elsif :new.sys_other is not null then
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'INSERT',:new.e_id,:new.sys_name,NULL,:new.sys_other);
end if;
CREATE TABLE source_det (
det_id number(10) by default IDENTITY
e_id NUMBER(10),
sys_name VARCHAR2(20),
ref_id NUMBER(10),
sys_other VARCHAR2(30)
);
INSERT INTO source_det VALUES(1,11,'SOURCE',992,null);
INSERT INTO source_det VALUES(2,11,'SOURCE',637,null);
INSERT INTO source_det VALUES(3,11,'SOURCE',null,'Manual');
INSERT INTO source_det VALUES(4,11,'TARGET',637,null);
INSERT INTO source_det VALUES(5,12,'TARGET',637,null);
Audit table:
CREATE SEQUENCE audit_tab_sq;
CREATE TABLE audit_tab (
a_id NUMBER(10) default audit_tab_sq.nextval,
l_transaction varchar2(20),--INSERT, UPDATE, DELETE
e_id NUMBER(10),
sys_name VARCHAR2(20),
value_old VARCHAR2(20),
value_new VARCHAR2(20)
);
I need to create a trigger that will get fired whenever there is new event occurred on the main table i.e source_det
我的尝试:
create or replace trigger audit_tab_trg
AFTER INSERT OR DELETE OR UPDATE ON source_det
FOR EACH ROW
BEGIN
--Need to insert records into the audit table whenever there is a new entry
IF inserting THEN
--new ref_id value
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'INSERT',:new.e_id,:new.sys_name,NULL,:new.ref_id);
--new sys_other
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'INSERT',:new.e_id,:new.sys_name,NULL,:new.sys_other);
END IF;
END;
当我将 ref_id
的一条记录插入 table source_Det
然后在审计中 table 我得到两条记录但理想情况下,它应该检查并仅加载新插入的值。
当前输出:
+------+---------------+------+----------+-----------+-----------+
| a_id | l_transaction | e_id | sys_name | value_old | value_new |
+------+---------------+------+----------+-----------+-----------+
| 1 | INSERT | 13 | TARGET | null | 637 |
| 2 | INSERT | 13 | TARGET | null | null |
+------+---------------+------+----------+-----------+-----------+
预期输出:
+------+---------------+------+----------+-----------+-----------+
| a_id | l_transaction | e_id | sys_name | value_old | value_new |
+------+---------------+------+----------+-----------+-----------+
| 1 | INSERT | 13 | TARGET | null | 637 |
+------+---------------+------+----------+-----------+-----------+
基本上,我需要检查两列 ref_id
和 sys_other
。如果只有 ref_id
被用户输入或被用户修改或被用户删除,那么它应该被标记为 inserted/updated/deleted 进入审核 table。
如果只有 sys_other
由用户输入或由用户修改或由用户删除,那么它应该被标记为 inserted/updated/deleted 进入审核 table.
为什么你不听我之前的建议?您真的应该将新的一对 new/old 列添加到审计 table 中,而不是将 所有内容 放入 value_old/value_new 因为 - 因为您不存储信息它代表什么 - 你必须猜测(这就是解决问题的方法)。
顺便说一句,如果您在同一语句中同时修改 REF_ID
和 SYS_OTHER
,您会怎么做?您必须首先检查您做了什么,然后插入(或不插入)一行。太多的代码以获得一点好处。
if :new.ref_id is not null then
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'INSERT',:new.e_id,:new.sys_name,NULL,:new.ref_id);
elsif :new.sys_other is not null then
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'INSERT',:new.e_id,:new.sys_name,NULL,:new.sys_other);
end if;