Добро пожаловать, Гость |
- Установка и настройка базы данных
- Обновление, применение патчей
- Оптимизация, настройка производительности
- Обучение, подготовка персонала, оптимизация
ТЕМА:
oracle cascade delete 12 года 1 мес. назад #4336
| Всем привет. Такой вот вопрос: что-то не могу в документации найти ответа. Есть родительская и дочерняя таблички. В дочерней - внешний ключ к родительской с кляузой ON DELETE CASCADE. Для обеих таблиц создан statement-level триггер BEFORE DELETE. Каков будет порядок вызова этих триггеров в случае, когда мы выполняем удаление данных из родительской таблицы??? Опытным путем я обнаружил, что первым в этом случае срабатывает триггер BEFORE DELETE для дочерней таблицы. Проверял в 9-ке и в 10-ке. Однако в документации, повторяюсь, на эту тему ничего не нашел. Что скажете? Спасибо. |
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе. |
Re: oracle cascade delete 12 года 1 мес. назад #4337
|
The Execution Model for Triggers and Integrity Constraint Checking:
Another words, it does not matter how many child table rows are deleted due to CASCADE DELETE, child table BEFORE DELETE trigger is executed only once - before DELETE statement on a parent table (user DELETE statement). SY. |
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе. |
Re: oracle cascade delete 12 года 1 мес. назад #4338
|
Yeah, I saw this in documentation. But does it mean I am right? And BEFORE DELETE for child table is always called first??? Please, look at this Tom Kyte answer for very similar question. Kyte claims that there's no specific firing order in this case. I suppose he means that, Oracle 9iR2 Database concepts Note: Although triggers of different types are fired in a specific order, triggers of the same type for the same statement are not guaranteed to fire in any specific order. For example, all BEFORE row triggers for a single UPDATE statement may not always fire in the same order. Design your applications so they do not rely on the firing order of multiple triggers of the same type. As for me, I suppose this is true only if these "same-type" triggers are defined on the same table. Then I clearly understand that firing order is unpredictable. But I have two tables, as you can see... So, what do you think? Regards. |
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе. |
Re: oracle cascade delete 12 года 1 мес. назад #4339
|
Yes, in CASCADE DELETE/SET NULL context (otherwise BEFORE DELETE for child table trigger does not fire at all ). And documentation clearly states it - see section in red in my reply. Again, when delting from a parent table Oracle will check if any child tables have on DELETE CASCADE. For ones that do, Oracle will check for statement level BEFORE DELETE triggers. If there are any, Oracle will execute each of them not once for each delete statement (keep in mind, there will be as many child table delete statements as there are parent records to delete) but once, before deleting that child records (keep in mind, row level trigger behavior does not change - they will fire once for each deleted child record). After deleting all child records, Oracle will execute parent table BEFORE DELETE trigger. And only then, which is important, Oracle will execute any AFTER DELETE triggers on DELETE CASCADE child tables. Next step is AFTER DELETE trigger on parent table: |
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе. |
Re: oracle cascade delete 12 года 1 мес. назад #4340
| Видать сильно от версии зависит, или я гдето-то ошибся Сначала результат ниже тестOracle8i Enterprise Edition Release 8.1.6.0.0 - Production
|
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе. |
Re: oracle cascade delete 12 года 1 мес. назад #4341
| Я что-то не пойму: у Вас что, родительский BEFORE-триггер совсем не вызывается?... Вообще говоря, я склонен доверять SY. И мой исходный вопрос, в общем-то, важен для той задачи, которую я сейчас решаю. Одна из подзадач - ведение "лога" удаленных записей: т.е. записи, удаляемые как из родительской, так и из дочерней таблицы, вставляются в другую табличку в триггерах FOR EACH ROW. Однако загвоздка в том, что если записи дочерней таблицы удаляются не напрямую, а вследствие каскадного удаления, то помещать их в лог не нужно. Надеюсь, я ясно выражаюсь. Так вот, у меня сейчас есть два варианта решения этой проблемы: простой и более громоздкий. Простой предполагает использование переменной пакета и двух дополнительных before delete триггеров соответственно для родительской и дочерних таблиц. Однако, если порядок вызова последних триггеров при удалении из родительской таблицы все же непредсказуем, то страшновато такое использовать Насчет Вашего случая, могу сказать, что по поводу восьмерки на Металинке были похожие обсуждения. Интересно было бы услышать еще мнения. Спасибо. |
Пожалуйста Войти или Регистрация, чтобы присоединиться к беседе. |