Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Oracle Новый топик    Ответить
 Как триггером отловить неудачное завершение DML операции?  [new]
deleter
Guest
statement триггер before delete выставляет некую пакетную переменную-флажок.
statement триггер after delete его сбрасывает.

Но если delete свалился, то after statement trigger не сработает и флажок не сбросится.

Как можно корректно обработать ситуацию и всё-таки автоматически сбросить этот флажок при неудачном delete?
27 апр 07, 18:57    [4081287]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
очевидно, обрабатывать ошибки dml-ля (при исключении - кроме всего прочего, гасить флаг)
27 апр 07, 19:20    [4081358]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
deleter
Guest
orawish
очевидно, обрабатывать ошибки dml-ля (при исключении - кроме всего прочего, гасить флаг)

Не получится :(
Это триггеры на таблицу, а кто будет манипулировать данными - неизвестно, и для них всё должно быть прозрачно, без лишних приседаний.

На самом деле, это идёт борьба с мутированием parent table при FK "on delete cascade", когда триггеры на child table изменяют поля у родителя. Всё работает, кроме каскадного удаления - при удалении родителя, удаляется и потомок, а там триггер, который хочет изменить удаляемого родителя. Вот для этого флажок и нужен, чтобы не обращаться в родителю, когда его удаляют :)
27 апр 07, 19:39    [4081397]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
ну, что сказать? действительно, каскадные конструкции перпендикулярны восходящей денормализации. Имхо, если они обои вам дороги, без присяданий - не обойдется.
Наименьшее присядание, имхо, API-шечка на удаление мастера..
27 апр 07, 19:54    [4081429]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
ora_live
Member

Откуда: http://cleanmonday.ru/
Сообщений: 198
deleter

родителя. Вот для этого флажок и нужен, чтобы не обращаться в родителю, когда его удаляют :)


Так какую задачу вам нужно решить, логирование ошибок DML или разобраться с правильным удалением? Если первое и у вас 10g, то там есть логирование ошибок DML, в том числе гнерируемых триггерами.
27 апр 07, 23:29    [4081738]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
deleter
Guest
Мне нужно в поддерживать синхронность родителя и потомков, т.е. фактически имитировать денормализацию, как заметил orawish.
У меня 9i.

Еще вариант - как советует Oracle в доке - через temporary table (on commit delete rows, как я полагаю), но не хочется заводить новые объекты в базе...
И есть плохой вариант - удалить FK constraint и поддерживать целостность на процедурном уровне.

Но хочется какое-нибудь элегантное решение через пакетные переменные :)
28 апр 07, 00:47    [4081892]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
Вячеслав Любомудров
Member

Откуда: Владивосток
Сообщений: 18486
Попробовать выставлять/снимать блокировку через DBMS_LOCK
По крайняку, после commit/rollback транзакции она сбросится
28 апр 07, 03:18    [4082029]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
searcher_
Member

Откуда:
Сообщений: 39
deleter

...
Всё работает, кроме каскадного удаления - при удалении родителя, удаляется и потомок, а там триггер, который хочет изменить удаляемого родителя. Вот для этого флажок и нужен, чтобы не обращаться в родителю, когда его удаляют :)

Хм.. а что мешает в тригере потомка написать
if deleted then
  --не обращаемя
else
  --обращаемя
end if;
28 апр 07, 10:19    [4082579]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
deleter
Guest
автор
Попробовать выставлять/снимать блокировку через DBMS_LOCK
По крайняку, после commit/rollback транзакции она сбросится

Точно, попробую так сделать! Самый лучший флажок - это блокировка :)

searcher_
Хм.. а что мешает в тригере потомка написать

if deleted then
--не обращаемя
else
--обращаемя
end if;


Мешает. При удалении потомка родитель должен тоже проапдейтиться.
Но если потомок удаляется каскадно, то не должен, потому что мутирование.
Такая вот особенность.
28 апр 07, 12:00    [4083148]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 64002
Блог
deleter
И есть плохой вариант - удалить FK constraint и поддерживать целостность на процедурном уровне.

Зачем? FK нужно оставить, достаточно перенести каскад с FK на триггер. Тогда в этом триггере можно будет cбрасывать флаг вне зависимости от того, удалось удалить детей или нет.
28 апр 07, 12:28    [4083319]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
deleter
Guest
автор
Попробовать выставлять/снимать блокировку через DBMS_LOCK
По крайняку, после commit/rollback транзакции она сбросится

Хехе, не работает :(

Summary of DBMS_LOCK Subprograms
...
ALLOCATE_UNIQUE performs a commit
...

Картинка с другого сайта. Надо же...

автор
FK нужно оставить, достаточно перенести каскад с FK на триггер

Да, тоже вариант: On Delete No Action и удалять детей из триггера.
Только перед этим сделать UPDATE детей спец. значением, чтобы "сообщить" триггерам детей, что для этих строчек не надо при последующем удалении обращаться к родителю, т.к. родитель сейчас мутирует и будет удалён.
28 апр 07, 12:47    [4083405]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
softwarer
Member

Откуда: 127.0.0.1
Сообщений: 64002
Блог
deleter
Только перед этим сделать UPDATE детей спец. значением

Зачем? Флаг и будет таким значением. Не стоит решать дополнительными табличными операциями то, что можно решить в памяти сессии.
28 апр 07, 12:51    [4083429]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
дело, конечно, хозяйское.. Но я бы подумал над: покоцать ту денормализацию в сторону
вью/а мож. и матвью
28 апр 07, 12:51    [4083433]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
deleter
Guest
автор
Зачем? Флаг и будет таким значением. Не стоит решать дополнительными табличными операциями то, что можно решить в памяти сессии.

Так проблема в том, что если вдруг DELETE родителя обламывается, то флажок никто не сбросит до конца сессии или до первого успешного DELETE. И тогда триггеры детей не будут изменять родителя, если кто-нибудь захочет удалить этих детей.

Впрочем, это очень редкая ситуация.
Пожалуй оставлю как есть: флажок в пакете + каскадный FK. Для диагностики всё равно есть средства контроля целостности.
28 апр 07, 12:56    [4083456]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
orawish
Member

Откуда: Гадюкино-2 (City)
Сообщений: 15487
В принципе, возможна и такая крюзлятина: там, где сейчас выставляете флаг - вместо этого -
записывайте нечто (id/rowid мастера, а мож. и тот самый флаг) во временную таблицу
уровня транзакции. Ваша проблема несбрасывания флага сузится до границ транзакции,
что, имхо, достаточно документировать и можно заб(ы/и)ть..
28 апр 07, 13:00    [4083483]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
Grami
Member

Откуда: Москва
Сообщений: 451
deleter
автор
Зачем? Флаг и будет таким значением. Не стоит решать дополнительными табличными операциями то, что можно решить в памяти сессии.

Так проблема в том, что если вдруг DELETE родителя обламывается, то флажок никто не сбросит до конца сессии или до первого успешного DELETE. И тогда триггеры детей не будут изменять родителя, если кто-нибудь захочет удалить этих детей.

Впрочем, это очень редкая ситуация.
Пожалуй оставлю как есть: флажок в пакете + каскадный FK. Для диагностики всё равно есть средства контроля целостности.


видно не понял.
совсем на пальцах то что объяснил softwarer:

триггер на родителя:

begin
1. выставить флаг;
2. удалить чилдренов;
3. восстановить флаг;
exception
  если чё то
     восстановить флаг;
     raise;
end;
28 апр 07, 13:40    [4083730]     Ответить | Цитировать Сообщить модератору
 Re: Как триггером отловить неудачное завершение DML операции?  [new]
deleter
Guest
Grami
видно не понял.
совсем на пальцах то что объяснил softwarer:

Понял идею. Ставить и сбрасывать флажок для каждой строчки парента.
Спасибо за пояснение. Да, так, вроде, будет надёжно работать.
28 апр 07, 14:00    [4083860]     Ответить | Цитировать Сообщить модератору
Все форумы / Oracle Ответить