Sql 插入到執行觸發器(插入前)的同一個表中
Sql 插入到執行觸發器(插入前)的同一個表中,sql,,,,-,Sql,,,, ,我必須執行一個觸發器,該觸發器必須使用一個不同的值寫入同一列兩次,例如: 語句是: ON 我收到的數據是:12345,RAIL,075,HDFG但同時,我想在云中插入相同的數據,但如下所示:12345,鐵路,069,HDFG我寫了下面的代碼,但是我擔心觸發器會由于插入而陷入無限循環 or
我必須執行一個觸發器,該觸發器必須使用一個不同的值寫入同一列兩次,例如:
語句是:
BEFORE INSERT ON MXGLCOMP_CLOUD
我收到的數據是:12345,RAIL,075sql 觸發器 在插入前 改變值,HDFG
但同時,我想在云中插入相同的數據,但如下所示: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;
這樣行嗎?我該怎么辦?正如我之前所說,我沒有運行測試,因為我不想要無限循環
正如您已經懷疑的,您當前的代碼將循環,因為觸發器內的插入將導致觸發器再次觸發,而這將進行另一次插入,這將導致觸發器觸發,這將。。。等等,但將在發現這種情況時終止,間接:
ORA-00036: maximum number of recursive SQL levels (50) exceeded
ORA-06512: at "SCHEMA.MXGLCOMP_CLOUD_TRG", line 7
在這種情況下,避免這種情況很簡單:只需檢查插入的值sql 觸發器 在插入前 改變值,并且僅在
'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;
/
然后,向空表中進行一次插入將創建兩行:
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;
/
然后(再次從空表開始):
為什么要在觸發器中執行此操作?為什么不從應用程序中將兩個插入一起執行?如果075和069是固定值,那么在決定創建新行之前,通過檢查新行的值來避免無限循環(不是無限循環,它最終會失敗),這很簡單,但這似乎是個壞主意。為什么要物理存儲這兩行?為什么不從應用程序中將兩個插入一起發送?:此數據是由其他系統發送的,實際上它們像一樣發送,我必須將此更改為069和075。為什么還要物理存儲這兩行:使此值有助于創建兩個新結構,其中,如果需要添加的是069,例如069.智利,如果是075,我們需要添加075-秘魯,我們需要兩者。請閱讀-總結是,這不是解決志愿者問題的理想方式,可能會對獲得答案產生反作用。請不要在你的問題中添加這個。好的,看起來不錯。還有一個問題,如果我得到一行=GB,我需要兩行,一行=069,另一行=075,該怎么辦?我怎么能這么做?(不需要GB值)我知道這不是最好的方法,但我無法控制發送信息的系統,但客戶端希望這樣做。什么都沒有發生,只是插入了該行。你的問題沒有提到GB。只有075會導致額外的操作。如果你想讓不同的事情發生,那么就增加更多的條件,以及當它們被滿足時應該發生什么。我已經為你所描述的添加了一個示例。
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