2016-04-14 3 views
0

я получаю эти ошибки при обновлении таблицыOracle Mutating таблица - триггер ошибки

ORA-04091: table HAMZA.EXPEDITION is mutating, trigger/function may not see it 
ORA-06512: at "HAMZA.LIVRAISONFINIE", line 6 
ORA-04088: error during execution of trigger 'HAMZA.LIVRAISONFINIE' 

Ниже приведены таблицы, используемые

экспедиция (Id_Expedition, Date_Livraison);

Командир (Numero_Commande, ..);

cmdalivrer (id_cmd, id_etape);

CREATE OR REPLACE TRIGGER livraisonfinie 

AFTER UPDATE ON Expedition 
FOR EACH ROW 

DECLARE 
    date_liv Expedition.date_livraison%type; 

BEGIN 

    SELECT :NEW.date_livraison INTO date_liv from Expedition; 

    IF date_liv <> TO_DATE('00/00/00 00:00:00', 'yyyy/mm/dd hh24:mi:ss') 
    THEN 
     INSERT INTO Commande (etat) VALUES ('livree'); 

     DELETE FROM cmdalivrer CMD WHERE :NEW.numero_commande=CMD.id_cmd; 
     DELETE FROM Expedition E WHERE E.date_livraison = date_liv; 
    END IF ; 
END; 
/

Спасибо за помощь.

+1

Какова логика, которую вы пытаетесь реализовать? Почему вы выбираете из 'экспедиции' в первую очередь, а не просто присваиваете': new.date_livraison' 'date_liv', если есть причина иметь локальную переменную вообще? Что делает 'delete' из' экспедиции', пытающегося сделать? Триггер не может удалить строку, которая находится в процессе вставки. И сравнение с годом 0 даты кажется маловероятным. Это не похоже на то, что вы хотите выполнить, должно быть сделано с помощью такого триггера. –

+0

Его как база данных delivry. Когда пользователь обновляет атрибут date_livraison, это значит, что он получает delivred, поэтому я хочу удалить строки в cmdalivrer, где numero_livraison строки обновляется = cmdalivrer.id_cmd. затем удалите строку, которая просто загружается в Expedition (вот почему я использовал триггер AFTER. Наконец, если проверка, если атрибут date_livraison содержит 00-00-00 00:00:00 (это означает, что команда еще не получила delvred). (спасибо и извините за мой плохой английский) –

+0

Триггер на столе не сможет удалить строку, которая находится в процессе вставки (которая по-прежнему верна, является ли это триггером до или после строки). чем пользователь вставляет строку в таблицу, которая сразу же удаляется, не было бы более разумным для пользователя вызывать процедуру, которая просто удаляется из таблицы 'cmdaliverer'? –

ответ

0

Вы можете сделать то, что вы пытаетесь сделать с помощью триггера соединения:

CREATE OR REPLACE TRIGGER livraisonfinie_compound 
    AFTER UPDATE ON Expedition 
    COMPOUND TRIGGER 

    TYPE DATE_TABLE IS TABLE OF EXPEDITION.DATE_LIVRAISON%TYPE; 
    tblDates DATE_TABLE; 

    BEFORE STATEMENT IS 
    BEGIN 
    tblDates := DATE_TABLE(); 
    END BEFORE STATEMENT; 

    AFTER EACH ROW IS 
    BEGIN 
    IF :NEW.date_livraison <> TO_DATE('00/00/00 00:00:00', 'yyyy/mm/dd hh24:mi:ss') 
    THEN 
     INSERT INTO Commande (etat) VALUES ('livree'); 

     DELETE FROM cmdalivrer CMD WHERE :NEW.numero_commande=CMD.id_cmd; 

     tblDates.EXTEND; 
     tblDates(tblDates.LAST) := :NEW.date_livraison; 
    END IF ; 
    END AFTER EACH ROW; 

    AFTER STATEMENT IS 
    BEGIN 
    IF tblDates.COUNT > 0 THEN 
     FOR i IN tblDates.FIRST..tbDates.LAST LOOP 
     DELETE FROM Expedition E 
      WHERE E.date_livraison = tblDates(i); 
     END LOOP; 
    END IF; 
    END AFTER STATEMENT; 
END livraisonfinie_compound; 

You can read further on compound triggers here.

Удачи.

+0

Большое вам спасибо. но любой другой вариант без сложного триггера? –

+1

@ H.Hamza. Вместо этого вы можете иметь три отдельных триггера, пакет и коллекцию. Возможно, вы могли бы переименовать таблицу, создать представление с именем таблицы и создать вместо этого триггер на представлении. –

Смежные вопросы