插入执行触发器(插入之前)的相同 table

Insert into the same table where the trigger (before insert) is executed

我必须执行一个触发器,该触发器必须将同一列写入两次但具有一个不同的值,例如:

插入语句之前是:

BEFORE INSERT ON MXGLCOMP_CLOUD

我收到的数据是:12345,RAIL,075,HDFG

而且,我想将相同的数据插入 MXGLCOMP_CLOUD,但像这样: 12345,铁路,069,HDFG。

我写了下面的代码,但我担心触发器会因为我在同一个触发器中执行的插入而陷入无限循环。

create or replace TRIGGER MXGLCOMP_CLOUD_TRG 
BEFORE INSERT ON MXGLCOMP_CLOUD 
REFERENCING OLD AS OLD NEW AS NEW 
FOR EACH ROW 
BEGIN
    INSERT INTO MXGLCOMP_CLOUD (ACTIVE, COMPTEXT, COMPVALUE, EXTERNALREFID)
    VALUES (:NEW.ACTIVE, :NEW.COMPTEXT, '069', :NEW.EXTERNALREFID);
END;

这样可以吗?我必须做什么?正如我之前所说,我没有 运行 测试,因为我不想要那个无限循环。

正如您已经怀疑的那样,您当前的代码将循环,因为触发器内的插入将导致触发器再次触发,并且将执行另一个插入,这将导致触发器触发,这将......等等. 但是 Oracle 会在间接发现这种情况时终止:

 ORA-00036: maximum number of recursive SQL levels (50) exceeded
 ORA-06512: at "SCHEMA.MXGLCOMP_CLOUD_TRG", line 7

在这种情况下避免这种情况很简单:只需检查插入的值,如果它是 '075':

,则只插入另一个新行
create or replace trigger mxglcomp_cloud_trg 
before insert on mxglcomp_cloud 
for each row 
begin
  if :new.compvalue = '075' then
    insert into mxglcomp_cloud(active, comptext, compvalue, externalrefid)
    values(:new.active, :new.comptext, '069', :new.externalrefid);
  end if;
end;
/

然后在一个空 table 中插入一个单行创建两行:

insert into mxglcomp_cloud (active, comptext, compvalue, externalrefid)
values (12345, 'RAIL', '075', 'HDFG');

1 row inserted.

select * from mxglcomp_cloud;

    ACTIVE COMPTEXT   COM EXTERNALRE
---------- ---------- --- ----------
     12345 RAIL       069 HDFG      
     12345 RAIL       075 HDFG      

但是我仍然认为这不是一个好主意,您隐藏了业务逻辑和数据操作,并且会有用户可能无法预料的副作用。举一个明显的例子,当实际上有两行时,插入报告“插入了 1 行”,这令人困惑。

最好从应用程序层执行两次插入,或者将两者都放在一个过程中并让应用程序(以及其他所有人)调用它。


如果你真的想把'GB'改成两行,一排用'075',另一排用'069',那么你可以做同样的事情,但要测试'GB' 并将其值更改为 '075',同时仍然插入额外的行:

create or replace trigger mxglcomp_cloud_trg 
before insert on mxglcomp_cloud 
for each row 
begin
  if :new.compvalue = 'GB' then
    -- change this row from GB to 075
    :new.compvalue := '075';

    -- add another row for 069
    insert into mxglcomp_cloud(active, comptext, compvalue, externalrefid)
    values(:new.active, :new.comptext, '069', :new.externalrefid);
  end if;
end;
/

然后(再次从空 table 开始):

insert into mxglcomp_cloud (active, comptext, compvalue, externalrefid)
values (12345, 'RAIL', 'GB', 'HDFG');

1 row inserted.

select * from mxglcomp_cloud;

    ACTIVE COMPTEXT   COM EXTERNALRE
---------- ---------- --- ----------
     12345 RAIL       069 HDFG      
     12345 RAIL       075 HDFG