如何使用触发器将新条目的两条记录插入同一列
How to to insert two records for the new entry into the same column using triggers
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);
审计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)
);
我的尝试:
create or replace trigger audit_tab_trg
AFTER INSERT OR DELETE OR UPDATE ON source_det
FOR EACH ROW
BEGIN
--INSERTING
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);
elsif (:new.ref_id is not null) AND (: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.ref_id);
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;
问题陈述:
- 每当发生新的插入或更新时,我都需要在审计中插入一条记录 table。
当我为 ref_id
或 sys_other
提供单个值时,触发器工作正常,但在一次提供两个列值时触发器不工作,如下所述
INSERT INTO source_det VALUES (13, 'TARGET', 637, null);
加入审计table:
+------+---------------+------+----------+-----------+-----------+
| a_id | l_transaction | e_id | sys_name | value_old | value_new |
+------+---------------+------+----------+-----------+-----------+
| 1 | INSERT | 13 | TARGET | null | 637 |
+------+---------------+------+----------+-----------+-----------+
但是当我插入两个记录时,即 ref_id
和 sys_other
那么两个条目应该被插入到审计中 table
INSERT INTO source_det VALUES (15, 'SOURCE', 637, 'Upload');
当前输出:
+------+---------------+------+----------+-----------+-----------+
| a_id | l_transaction | e_id | sys_name | value_old | value_new |
+------+---------------+------+----------+-----------+-----------+
| 1 | INSERT | 15 | SOURCE | null | 637 |
+------+---------------+------+----------+-----------+-----------+
预期输出:
+------+---------------+------+----------+-----------+-----------+--+
| a_id | l_transaction | e_id | sys_name | value_old | value_new | |
+------+---------------+------+----------+-----------+-----------+--+
| 1 | INSERT | 15 | SOURCE | null | 637 | |
| 2 | INSERT | 15 | SOURCE | null | Upload | |
+------+---------------+------+----------+-----------+-----------+
更新方法相同:
下面是我试过的
if (:old.ref_id != :new.ref_id ) then
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'UPDATE',:old.e_id,:old.sys_name,:old.ref_id,:new.ref_id);
elsif (:old.sys_other != :new.sys_other ) then
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'UPDATE',:old.e_id,:old.sys_name,:old.sys_other,:new.sys_other);
end if;
使用的工具:SQL Developer(18c)
应重新排列 IF,以便“首先”检查“最后”(在您的代码中):
SQL> create or replace trigger audit_tab_trg
2 after insert or delete or update on source_det
3 for each row
4 begin
5 if (:new.ref_id is not null) and (:new.sys_other is not null) then
6 insert into audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
7 values (audit_tab_sq.nextval,'INSERT',:new.e_id,:new.sys_name,null,:new.ref_id);
8 insert into audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
9 values (audit_tab_sq.nextval,'INSERT',:new.e_id,:new.sys_name,null,:new.sys_other);
10 elsif :new.ref_id is not null then
11 insert into audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
12 values (audit_tab_sq.nextval,'INSERT',:new.e_id,:new.sys_name,null,:new.ref_id);
13 elsif :new.sys_other is not null then
14 insert into audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
15 values (audit_tab_sq.nextval,'INSERT',:new.e_id,:new.sys_name,null,:new.sys_other);
16 end if;
17 end;
18 /
Trigger created.
测试:
SQL> insert into source_det (det_id, e_id, sys_name, ref_id, sys_other)
2 values (audit_tab_sq.nextval, 15, 'SOURCE', 637, 'Upload');
1 row created.
SQL> select * from audit_tab;
A_ID L_TRANSACTION E_ID SYS_NAME VALUE_OLD VALUE_NEW
---------- -------------------- ---------- -------------------- -------------------- --------------------
10 INSERT 15 SOURCE 637
11 INSERT 15 SOURCE Upload
SQL>
Testing : we can reduce the code for code redundancy. find below updated code.
create or replace trigger audit_tab_trg
after insert or delete or update on source_det
for each row
begin
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);
end if;
if :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;
end;
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);
审计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)
);
我的尝试:
create or replace trigger audit_tab_trg
AFTER INSERT OR DELETE OR UPDATE ON source_det
FOR EACH ROW
BEGIN
--INSERTING
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);
elsif (:new.ref_id is not null) AND (: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.ref_id);
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;
问题陈述:
- 每当发生新的插入或更新时,我都需要在审计中插入一条记录 table。
当我为 ref_id
或 sys_other
提供单个值时,触发器工作正常,但在一次提供两个列值时触发器不工作,如下所述
INSERT INTO source_det VALUES (13, 'TARGET', 637, null);
加入审计table:
+------+---------------+------+----------+-----------+-----------+
| a_id | l_transaction | e_id | sys_name | value_old | value_new |
+------+---------------+------+----------+-----------+-----------+
| 1 | INSERT | 13 | TARGET | null | 637 |
+------+---------------+------+----------+-----------+-----------+
但是当我插入两个记录时,即 ref_id
和 sys_other
那么两个条目应该被插入到审计中 table
INSERT INTO source_det VALUES (15, 'SOURCE', 637, 'Upload');
当前输出:
+------+---------------+------+----------+-----------+-----------+
| a_id | l_transaction | e_id | sys_name | value_old | value_new |
+------+---------------+------+----------+-----------+-----------+
| 1 | INSERT | 15 | SOURCE | null | 637 |
+------+---------------+------+----------+-----------+-----------+
预期输出:
+------+---------------+------+----------+-----------+-----------+--+
| a_id | l_transaction | e_id | sys_name | value_old | value_new | |
+------+---------------+------+----------+-----------+-----------+--+
| 1 | INSERT | 15 | SOURCE | null | 637 | |
| 2 | INSERT | 15 | SOURCE | null | Upload | |
+------+---------------+------+----------+-----------+-----------+
更新方法相同:
下面是我试过的
if (:old.ref_id != :new.ref_id ) then
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'UPDATE',:old.e_id,:old.sys_name,:old.ref_id,:new.ref_id);
elsif (:old.sys_other != :new.sys_other ) then
INSERT INTO audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
VALUES (audit_tab_sq.NEXTVAL,'UPDATE',:old.e_id,:old.sys_name,:old.sys_other,:new.sys_other);
end if;
使用的工具:SQL Developer(18c)
应重新排列 IF,以便“首先”检查“最后”(在您的代码中):
SQL> create or replace trigger audit_tab_trg
2 after insert or delete or update on source_det
3 for each row
4 begin
5 if (:new.ref_id is not null) and (:new.sys_other is not null) then
6 insert into audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
7 values (audit_tab_sq.nextval,'INSERT',:new.e_id,:new.sys_name,null,:new.ref_id);
8 insert into audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
9 values (audit_tab_sq.nextval,'INSERT',:new.e_id,:new.sys_name,null,:new.sys_other);
10 elsif :new.ref_id is not null then
11 insert into audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
12 values (audit_tab_sq.nextval,'INSERT',:new.e_id,:new.sys_name,null,:new.ref_id);
13 elsif :new.sys_other is not null then
14 insert into audit_tab (a_id,l_transaction,e_id, sys_name,value_old,value_new)
15 values (audit_tab_sq.nextval,'INSERT',:new.e_id,:new.sys_name,null,:new.sys_other);
16 end if;
17 end;
18 /
Trigger created.
测试:
SQL> insert into source_det (det_id, e_id, sys_name, ref_id, sys_other)
2 values (audit_tab_sq.nextval, 15, 'SOURCE', 637, 'Upload');
1 row created.
SQL> select * from audit_tab;
A_ID L_TRANSACTION E_ID SYS_NAME VALUE_OLD VALUE_NEW
---------- -------------------- ---------- -------------------- -------------------- --------------------
10 INSERT 15 SOURCE 637
11 INSERT 15 SOURCE Upload
SQL>
Testing : we can reduce the code for code redundancy. find below updated code.
create or replace trigger audit_tab_trg
after insert or delete or update on source_det
for each row
begin
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);
end if;
if :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;
end;