如何使用触发器将新条目的两条记录插入同一列

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;

问题陈述:

  1. 每当发生新的插入或更新时,我都需要在审计中插入一条记录 table。

当我为 ref_idsys_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_idsys_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;