我有一个配置表,其中包含用于控制应用程序中进程的记录。通常情况下,我会让应用程序控制该表,但是现在它是不可能的(没有钱,没有时间等)。因此,目前该表将由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
条件如下:
所以我的问题是,有没有办法让这项工作也在更新?我已经读过关于使用物化视图的触发器,但我想我可能会遇到表和视图之间的数据不同步的问题。
感谢您的帮助! 人
PS。使用Oracle Release 12.1.0.2.0
更新:这是on INSERT触发器:
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
答案 0 :(得分:1)
当语句导致触发器触发并且该触发器引用导致触发器的表时,会发生ORA-04091:表CLDBDEF.CTL_WEBADMIN_ABGLEICH正在变异, 触发器/功能可能看不到它
如何避免:
参考: -