插入执行触发器(插入之前)的相同 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
我必须执行一个触发器,该触发器必须将同一列写入两次但具有一个不同的值,例如:
插入语句之前是:
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