我嘗試創建一個正確創建的自定義表。最后 2 個欄位與 Orders 表中的型別匹配。觸發器的想法是當某個日期欄位更改為將其插入到新表中時。觸發器是在 Oracle 中正確創建的,但是一旦相關欄位發生更改,我就會收到 ORA 錯誤(如下)并且無法找出它們出現的原因。
ORA-06519: 檢測到活動的自主事務并回滾
ORA-06512: 在“shc.trigger_table_1”,第 20 行
ORA-04088: 執行觸發器 'shc.trigger_table_1' 期間出錯
我嘗試更改資料型別,嘗試引入例外,嘗試洗掉 :old.info23 檢查。
這是我正在創建的表:
CREATE TABLE table1(
id number generated by default as identity,
table_name varchar2(20),
field_changed varchar2(20),
old_value date,
new_value date,
changed_by varchar(20),
date_of_change date,
orderRef varchar(50),
Ref varchar2(256));
這是有問題的觸發器:
CREATE OR REPLACE TRIGGER trigger_table_1
AFTER UPDATE ON consignment
FOR EACH ROW
DECLARE
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
DECLARE
my_AEXTERNAUFTRAGSNR varchar2(50);
my_AUFTRAGSREFERENZ2 varchar2(256);
BEGIN
IF :OLD.ANKUNFTBELDATUMVON <> :NEW.ANKUNFTBELDATUMVON AND :old.info23='I' THEN
Select AEXTERNAUFTRAGSNR, AUFTRAGSREFERENZ2
Into my_AEXTERNAUFTRAGSNR, my_AUFTRAGSREFERENZ2
From orders
Where orders.nr = :old.ordernr;
insert into table1(table_name, field_changed, old_value, new_value, changed_by, date_of_change, orderRef, Ref)
values ('consignment', 'ANKUNFTBELDATUMVON', :OLD.ANKUNFTBELDATUMVON, :NEW.ANKUNFTBELDATUMVON, sys_context('userenv','OS_USER'), SYSDATE, my_AEXTERNAUFTRAGSNR, my_AUFTRAGSREFERENZ2);
END IF;
END;
END;
uj5u.com熱心網友回復:
直接的問題是您沒有提交您的自主事務。如果您將其更改為最后提交:
...
END IF;
END;
commit;
END;
/
然后它將起作用-小提琴。(你不需要嵌套塊,但它不會阻止它作業......你insert ... select ...可以避免需要任何區域變數......)
但正如您從 db<>fiddle 結果中看到的那樣,如果consignment回滾更新,則保留插入table1,因為這是獨立提交的。
如果您洗掉它,PRAGMA AUTONOMOUS_TRANSACTION;那么就不會發生這種情況。那么你就不需要而且確實不能在觸發器內提交。你只需要:
CREATE OR REPLACE TRIGGER trigger_table_1
AFTER UPDATE ON consignment
FOR EACH ROW
DECLARE
my_AEXTERNAUFTRAGSNR varchar2(50);
my_AUFTRAGSREFERENZ2 varchar2(256);
BEGIN
IF :OLD.ANKUNFTBELDATUMVON <> :NEW.ANKUNFTBELDATUMVON AND :old.info23='I' THEN
Select AEXTERNAUFTRAGSNR, AUFTRAGSREFERENZ2
Into my_AEXTERNAUFTRAGSNR, my_AUFTRAGSREFERENZ2
From orders
Where orders.nr = :old.ordernr;
insert into table1(table_name, field_changed, old_value, new_value, changed_by, date_of_change, orderRef, Ref)
values ('consignment', 'ANKUNFTBELDATUMVON', :OLD.ANKUNFTBELDATUMVON, :NEW.ANKUNFTBELDATUMVON, sys_context('userenv','OS_USER'), SYSDATE, my_AEXTERNAUFTRAGSNR, my_AUFTRAGSREFERENZ2);
END IF;
END;
/
或與insert ... select ...:
CREATE OR REPLACE TRIGGER trigger_table_1
AFTER UPDATE ON consignment
FOR EACH ROW
BEGIN
IF :OLD.ANKUNFTBELDATUMVON <> :NEW.ANKUNFTBELDATUMVON AND :old.info23='I' THEN
insert into table1(table_name, field_changed,
old_value, new_value,
changed_by, date_of_change,
orderRef, Ref)
select 'consignment', 'ANKUNFTBELDATUMVON',
:OLD.ANKUNFTBELDATUMVON, :NEW.ANKUNFTBELDATUMVON,
sys_context('userenv','OS_USER'), SYSDATE,
o.AEXTERNAUFTRAGSNR, o.AUFTRAGSREFERENZ2
from orders o
where o.nr = :old.ordernr;
END IF;
END;
/
小提琴
順便說一句,如果您只想在更新陳述句中包含特定列(或多列)時觸發觸發器,那么您可以執行以下操作:
AFTER UPDATE OF ANKUNFTBELDATUMVON ON consignment
但您仍然需要檢查它是否實際發生了變化。您當前的檢查不包括ANKUNFTBELDATUMVON更新為 null 或從 null 更新,如果該列可以為 null,這只是一個潛在的問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/530925.html
