簡體   English   中英

包含觸發器條件的表的INSERT和UPDATE上的ORACLE觸發器

[英]ORACLE Trigger on INSERT and UPDATE for table containing the trigger condition

我有一個配置表,其中包含用於控制應用程序中進程的記錄。 通常,我會由應用程序控制該表,但是現在這是不可能的(沒有錢,沒有時間等)。 因此,目前該表將由諸如SQL Developer之類的客戶端管理。 為了確保正確填充表,我需要一個觸發器,因為檢查約束不適用於自定義函數。 INSERT上的觸發器可以正常工作,但是我對UPDATE上的觸發器有麻煩,因為所有要檢查觸發器的條件都在表本身中,我從ORACLE中得到一個錯誤,該表目前正在更新,所以觸發器不能被觸發。

該表包含以下幾列:

ID, SOURCE_SYSTEM, TARGET_SYSTEM, TABLE_ID, VALID_FROM, VALID_THROUGH
 1,             2,             3,      455, 01.12.2011.    02.11.2013

條件如下:

  • 不能有具有相同SOURCE_SYSTEM,TARGET_SYSTEM和TABLE_ID的新記錄以及與現有記錄重疊的DATES-NEW.VALID_FROM和NEW.VALID_THROUGH必須在現有期限之外。 對於示例-兩者都必須為<01.12.2011或> 02.11.2013。

所以我的問題是,有沒有辦法使這項工作也適用於UPDATE? 我已經讀過關於將物化視圖用於觸發器的信息,但是我認為表和視圖之間的數據不同步可能會出現問題。

謝謝您的幫助!

PS。 使用Oracle版本12.1.0.2.0

更新:這是在插入觸發器:

create or replace 
trigger SINGLE_QUELLSYSTEM_INSERT
BEFORE INSERT ON CTL_WEBADMIN_ABGLEICH FOR EACH ROW
DECLARE 
    v_count_rows NUMBER;
BEGIN
  dbms_output.ENABLE (buffer_size => NULL);
  dbms_output.put_line('Start...');

  IF(:NEW.CLDB_QUELLSYSTEM_ID = :NEW.CLDB_ZIELSYSTEM_ID) THEN
    RAISE_APPLICATION_ERROR(-20336, 'Quellsystem ist gleich dem Zielsystem. Bitte, korrigieren Sie Ihre Abfrage.');
  END IF;

  IF(:NEW.GUELTIG_BIS < :NEW.GUELTIG_VON) THEN
    RAISE_APPLICATION_ERROR(-20338, 'Datum BIS liegt vor Datum VON. Bitte, korrigieren Sie Ihre Abfrage.');
  END IF;     

  SELECT COUNT(*) INTO v_count_rows FROM CTL_WEBADMIN_ABGLEICH;
  dbms_output.put_line('Anzahl der Zeilen in der Tabelle CTL_WEBADMIN_ABGLEICH: ' || v_count_rows);
  IF (v_count_rows >=1 ) THEN
    dbms_output.put_line('Mehrere Zeilen in der Tabelle CTL_WEBADMIN_ABGLEICH vorhanden. Checking trigger condition...');
    -- FOR r in (SELECT DISTINCT CLDB_QUELLSYSTEM_ID,CLDB_WEBADMIN_TABLE_ID, GUELTIG_BIS, GUELTIG_VON FROM CTL_WEBADMIN_ABGLEICH where GUELTIG_VON >= sysdate )
    FOR r in (SELECT DISTINCT CLDB_QUELLSYSTEM_ID,CLDB_WEBADMIN_TABLE_ID, GUELTIG_BIS, GUELTIG_VON FROM CTL_WEBADMIN_ABGLEICH)
    LOOP
      IF ((r.CLDB_QUELLSYSTEM_ID != :NEW.CLDB_QUELLSYSTEM_ID OR r.CLDB_QUELLSYSTEM_ID = :NEW.CLDB_QUELLSYSTEM_ID) and r.CLDB_WEBADMIN_TABLE_ID = :NEW.CLDB_WEBADMIN_TABLE_ID ) THEN
      dbms_output.put_line('Ein anderes Quellsystem wurde für das System: ' || r.CLDB_QUELLSYSTEM_ID || ' schon spezifiziert. Checking Gültigkeit...');
        IF (r.GUELTIG_BIS is null OR (:NEW.GUELTIG_BIS >= r.GUELTIG_VON AND :NEW.GUELTIG_BIS <= r.GUELTIG_BIS) OR 
            (:NEW.GUELTIG_VON >= r.GUELTIG_VON AND :NEW.GUELTIG_VON <= r.GUELTIG_BIS) OR 
            (:NEW.GUELTIG_VON <= r.GUELTIG_VON AND :NEW.GUELTIG_BIS >= r.GUELTIG_BIS)) THEN
            RAISE_APPLICATION_ERROR(-20337, 'Gültigkeitsbereiche mit schon existierenden Einträgen kollidieren!');
        END IF;
      END IF;
    END LOOP;
  END IF;
END;

除了聲明部分(即聲明部分)外,on UPDATE觸發器是相同的

create or replace 
trigger SINGLE_QUELLSYSTEM_UPDATE
BEFORE UPDATE ON CTL_WEBADMIN_ABGLEICH FOR EACH ROW ...

我得到的錯誤是:

ORA-04091: table CLDBDEF.CTL_WEBADMIN_ABGLEICH is mutating, trigger/function may not see it

ORA-04091:表CLDBDEF.CTL_WEBADMIN_ABGLEICH正在突變,觸發器/函數可能看不到它

當語句導致觸發觸發器並且該觸發器引用了導致該觸發器的表時,就會發生“ 變異錯誤”

如何避免:

  1. 不要使用觸發器
  2. 使用“之后”或“代替”觸發器
  3. 重做觸發器語法
  4. 使用自主交易

參考:-

修復Oracle Mutating錯誤

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM