目前我正在實現一個過程,該過程在模板外的某些相關表中創建了幾行。因此,我的過程包含SAVEPOINT
後跟一些INSERT
語句在不同的表上,以及一個Cursor用於在引用新創建的主鍵時將更多行插入到其他表中。帶有嵌套的原子事務BEFORE INSERT/UPDATE觸發器
每個這些表的定義了一個BEFORE INSERT/UPDATE觸發器,其目的到:
- 獲得從序新的主鍵,如果沒有在INSERT語句中定義(有這樣的情況:我需要明確地設置主鍵稍後引用它在同一事務)
- 設置一些默認值,如果他們是NULL
- 設置審覈字段(last_change_date,last_change_user,等..)
交易失敗ORA-04091:表變異,觸發/功能可能無法看到它
我的理解,我可以解決此,通過在每個觸發器聲明PRAGMA自治事務,但我的交易將不再是原子,因爲它是所有這些數據集應該作爲一個整體創建/插入的要求,或者它們都不是。
那麼我在做數據庫設計時做錯了什麼?
UPDATE:這是觸發的代碼
CREATE TRIGGER TRG_AUFTRAG_B_IU
BEFORE INSERT OR UPDATE
ON AUFTRAG
FOR EACH ROW
BEGIN
IF INSERTING THEN
IF :new.id is NULL or :new.id = 0 THEN
SELECT SEQ_AUFTRAG.nextval into :new.id from dual;
END IF;
IF :new.nummer is NULL or :new.nummer = 0 THEN
SELECT nvl(MAX(NUMMER),0)+1 INTO :new.nummer FROM AUFTRAG WHERE EXTRACT(YEAR from DATUM) = EXTRACT(YEAR from :new.DATUM);
END IF;
--DEFAULT Values
IF :new.BETR_GRENZWERTE_RELEVANT is NULL THEN
SELECT 0 INTO :new.BETR_GRENZWERTE_RELEVANT FROM dual;
END IF;
IF :new.DOKUMENTE_ABGELEGT is NULL THEN
SELECT 0 INTO :new.DOKUMENTE_ABGELEGT FROM dual;
END IF;
IF :new.EXT_ORG is NULL or :new.EXT_ORG < 1 THEN
SELECT 1 INTO :new.EXT_ORG FROM dual;
END IF;
:new.ERSTELLT_VON := nvl(:new.ERSTELLT_VON,user);
:new.ERSTELLT_DATUM := nvl(:new.ERSTELLT_DATUM,sysdate);
END IF;
:new.GEAENDERT_VON := user;
:new.GEAENDERT_DATUM := sysdate;
END;
請向我們展示您的觸發器代碼。實際上你列出的動作對於觸發器來說是非常典型和有用的,它們應該沒有任何問題地工作。 –
看起來你正在觸發器內的同一個表中執行一個'select'。根據你所說的觸發器需要做的事情,沒有任何「選擇」的要求。你說得對 - '編譯自主事務'不能解決這類問題。 –
啊!我想我已經看到了什麼問題......這是:新:NUMMER部分是不是?這是爲了創建一個業務需求的識別號碼。它會在AFTER INSERT TRIGGER中做到這一點嗎? –