Получил стол, на котором есть ключ:
+----+-----------+-----------+
+ ID + ID_PARENT + IS_PARENT +
+----+-----------+-----------+
+ 1 + (null) + 0 +
+ 2 + (null) + 1 +
+ 3 + 2 + 0 +
+----+-----------+-----------+
Как видите, идентификатор 1
сам по себе, 3
является потомком 2
.
Теперь я хочу иметь триггер, который на INSERT / UPDATE ...
- ошибки, если вставленная строка является собственным родителем (невозможно)
- , если у него есть
ID_PARENT
, установите для IS_PARENT
родителя значение 1
Это мой подход:
CREATE OR REPLACE TRIGGER tri_table_set_parent
BEFORE
INSERT OR UPDATE ON table
FOR EACH ROW
WHEN ( new.id_parent IS NOT NULL )
BEGIN
IF :new.id = :new.id_parent
THEN
RAISE_APPLICATION_ERROR(-20666, 'A gap cant be the parent of itself. More information here: https://youtu.be/hqRZFWE1X_A');
END IF;
UPDATE table
SET is_parent = 1
WHERE id = :new.id_parent;
END;
/
Ошибка работает так, как задумано, уууу! Но сейчас при вставке у меня проблемы.
При вставке строки без ID_PARENT
это работает (потому что триггер не сработает вообще).
Вставить строку, родитель которой ID_PARENT = (null)
:
INSERT INTO table (ID, ID_PARENT) VALUES (4, 1);
-> Работает!
Но вставив строку, родитель которой получил ID_PARENT
:
INSERT INTO table (ID, ID_PARENT) VALUES (5, 3);
-> Ошибки:
ORA-04091: Tabelle TABLE wird gerade geändert, Trigger/Funktion sieht dies möglicherweise nicht
ORA-06512: in "TRI_TABLE_SET_PARENT", Zeile 6
ORA-04088: Fehler bei der Ausführung von Trigger "TRI_TABLE_SET_PARENT"
ORA-06512: in "TRI_TABLE_SET_PARENT", Zeile 6
ORA-04088: Fehler bei der Ausführung von Trigger "TRI_TABLE_SET_PARENT"
Обновление таблицы вообще не работает, та же ошибка.
Хорошо, я понимаю, что не могу выбрать то, что может быть изменено одновременно. Но я обновляю, а также проверяю, что я не ссылаюсь на те же строки.
Так чего мне не хватает?