2015-02-25 6 views
0

Помогите, я очень новичок в триггере оракула. То, что я пытаюсь сделать, это когда удаление C последней строки B, A не имеет B. Поэтому я создать триггер на C.Ошибка мутирования в Oracle trigger

CREATE OR REPLACE TRIGGER child_check  
BEFORE DELETE DELETE ON C 

    REFERENCING OLD as OLD 
FOR EACH ROW DECLARE  
rowcnt number; 
rowcnt1 number; 

BEGIN 
    SELECT COUNT(*) INTO rowcnt FROM C WHERE colB = :OLD.colB; 
    IF rowcnt > 1 THEN 
    DBMS_OUTPUT.PUT_LINE('DELETE'); 
     DELETE C WHERE ROWID = :OLD.ROWID; 
    ELSE 
     SELECT COUNT(*) INTO rowcnt1 FROM A WHERE colB = :OLD.colB; 
     IF rowcnt1 > 1 THEN 
     DBMS_OUTPUT.PUT_LINE('B IS USED IN A. C CANNOT REMOVE ALL OF B'); 
      ELSE 
      DBMS_OUTPUT.PUT_LINE('DELETE'); 
      DELETE C WHERE ROWID = :OLD.ROWID; 
      DELETE B WHERE colB = :OLD.colB; 
     END IF;  
     END IF; 

END;/

    TABLE A | TABLE B | TABLE C 
colA | colB | colB | colC | colB 

A.colA является PK B.colB является PK C.colC является PK

A.colB FK из B.colB C.colB FK из B.colB

Существует меняющийся ошибка. Я занимаюсь поиском Google, и я понимаю, что есть что-то связанное с удалением. Я не могу найти конкретное решение Может кто-нибудь просветить меня как и что изменить в запросе удаления?

+0

Вы пытаетесь удалить ту же таблицу, где запускается триггер ... Я не понимаю, почему вы пытаетесь это сделать? – Sathya

+0

Вы ищете [внешние ключи с удалением каскада] (http://www.techonthenet.com/oracle/foreign_keys/foreign_delete.php) вместо триггера? –

+0

Привет, я добавил таблицу для лучшего понимания. Существует ограничение на ограничение на ограничение на C и A, поэтому, если мне нужно удалить любые данные из B, C и A, поскольку дочерние элементы должны удалить, прежде чем я смогу удалить B. Что мне нужно. Я хочу удалить C., но если данные в C являются последней записью, я должен убедиться, что A не имеет B, прежде чем удалять C последнюю запись. –

ответ

1

В Oracle вы не можете выполнить выбор, вставить, обновить или удалить в таблице триггер уровня строки. В вашем случае триггер находится на C, поэтому вы не можете удалять записи из C.

Ваш триггер кажется немного странным. Триггер срабатывает, когда запись удаляется с C. И затем триггер также удаляет эту запись с C. Это необязательно. Запись будет удалена.

Удаление из B возможно.

Ваш код трудно понять. B - столбец в C, но также имя таблицы? Очень смущает.

+0

Извините, но ограничение ограничения внешнего ключа отсутствует. B не может быть удалено, если присутствует A или C. –

+1

Спецификация: I a ** ROW LEVEL ** Trigger (с предложением 'FOR EACH ROW') вы не можете выполнить DML или SELECT в таблице, где включен триггер. 'SELECT' не является DML. Есть exceptoins: [Почему я не получаю ошибку мутирующей таблицы в триггере?] (Http://dba.stackexchange.com/questions/29244/why-am-i-not-getting-a-mutating-table-error -in-trigger) –

+0

Спасибо Wernfried. Сделал некоторые изменения. – Rene

0

Также помимо Mutating Trigger ошибки это может также вызвать триггеры для выполнения рекурсивно и потерпеть неудачу, как ваш Delete (на c) заявление в trigger бы начать в другой trigger, и это происходит постоянно.