Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Каскады в триггерах, Исполнение триггера до и после операции.
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. Заранее приношу извенение уважаемые коллеги за кажущийся банальным вопрос, но это для профи, а для начинающего на MSSQL он таки не кажется. У меня вопрос о том, как выполнить каскадное удаление с использованием триггеров. Я ранее работал на ORACLE и там при описании триггера был параметр BEFORE или AFTER {UPDATE|INSERT|DELETE} а здесь, как я понял триггер выполняется только после выполнения команды, т.е. когда уже удалена запись, но если наложено ограничение целостности по ключам между родительской и дочерней таблицами, то выполнение удаления не происходит. Нельзя удалить родителя без предварительного удаления дочерних записей. И еще вопрос, как узнать какое событие вызвало триггер, INSERT, UPDATE, DELETE. К примеру в ORACLE есть переменные которые можно анализировать внутри триггера (If inserting ... or deleting и т.д.) Если кто может ответить заранее благодарю. Пример кода на PL/SQL как его сделать в MSSQL create or replace trigger ACC_NEW_BEFORE before insert or update or delete on acc for each row declare -- local variables here tempsign varchar2(65); begin if INSERTING then --INSERT :new.owner := uid; :new.createdate := sysdate; :new.modifycount := 0; -- Ôîðìèðóåì ïîëíûé íîìåð ñ÷åòà if :NEW.parent != 0 then select fullacc into tempsign from acc where rectell = :NEW.parent; if tempsign is not null then :NEW.FULLACC := tempsign||'-'||:NEW.CTSIGN; else :NEW.FULLACC := :NEW.CTSIGN; end if; end if; elsif UPDATING then --UPDATE :new.modifydate := sysdate; :new.modifycount := :old.modifycount+1; :new.modifier := uid; elsif DELETING then --DELETE NULL; else NULL; end if; end ACC_NEW_BEFORE; С уважением, Сергей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.03.2002, 10:19 |
|
||
|
Каскады в триггерах, Исполнение триггера до и после операции.
|
|||
|---|---|---|---|
|
#18+
И еще вопрос, как узнать какое событие вызвало триггер, INSERT, UPDATE, DELETE В MSSQL есть две специальные таблицы INSERTED и DELETED, стурктура такая же как и у обновляемой таблицы. В них хранятся вставляемые и удаляемые данные. Т.о. если INSERTED пуста, то операция - удаление и т.д. У меня вопрос о том, как выполнить каскадное удаление с использованием триггеров В MSSQL2000 можно при указании внешнего ключа указывать и каскадное обновление(удаление) FOREIGN KEY (IdParent) REFERENCES tblParent (Id) ON DELETE CASCADE или FOREIGN KEY (IdParent) REFERENCES tblParent (Id) ON DELETE NO action, а в триггере INSTEAD OF удаляешь сначала из связанных таблиц, а потом из нее самой. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.03.2002, 10:57 |
|
||
|
Каскады в триггерах, Исполнение триггера до и после операции.
|
|||
|---|---|---|---|
|
#18+
Sergey, Вы совершенно правы, выполнение AFTER-триггера происходит после того, как проверяются ограничения, след., реализовать каскадное удаление / обновление с его помощью нельзя. В SQL Server нет BEFORE-триггеров, но есть триггеры INSTEAD OF, к-е выполняются не до, а вместо действия, вызвавшего включение триггера. В данном случае это различие не играет роли (с точностью до одного дополнительного оператора): create trigger tr1 on Customers instead of delete as delete from Orders where CustomerID in (select CustomerID from deleted) delete from Customers where CustomerID in (select CustomerID from deleted) В SQL Server триггер определяется на операцию, поэтому если Вам требуется заложить для UPDATE и для DELETE разные действия, то проще всего создать два отдельных триггера. Т.е. не create trigger ... for update, delete, а create trigger ... for update, create trigger ... for delete. И последнее: если Вам нужна только ссылочная целостность, то зачем писать триггеры? Не проще ли ее задать на декларативном уровне: ALTER TABLE Orders ADD CONSTRAINT [FK_Orders_Customers] FOREIGN KEY (CustomerID) REFERENCES Customers (CustomerID) ON DELETE CASCADE ON UPDATE CASCADE ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.03.2002, 11:09 |
|
||
|
Каскады в триггерах, Исполнение триггера до и после операции.
|
|||
|---|---|---|---|
|
#18+
Sorry, пока писал ответ, Alex A уже ответил, так что моя реплика - это не попытка его поправить или дополнить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.03.2002, 11:13 |
|
||
|
Каскады в триггерах, Исполнение триггера до и после операции.
|
|||
|---|---|---|---|
|
#18+
IMHO 100% гарантию определения действия может пока дать только написание триггера только на INSERT либо UPDATE либо DELETE 99% гарантию может дать проверка таблиц inserted и deleted. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.03.2002, 11:23 |
|
||
|
Каскады в триггерах, Исполнение триггера до и после операции.
|
|||
|---|---|---|---|
|
#18+
Мои 5 копеек. Мне кажется, для MSSQL обычно DRI делают или на констрейнтах или на триггерах, не смешивая их. Может быть до последнего времени это так было (до появления INSTEAD OF триггеров). Но в этом случае (если не делаем FOREIGN KEY), то можно и AFTER триггером пользоваться. Другое дело, что страшновато кажется, что ненадёжно. А что касается определения на какую операцию сработал триггер, то здесь я думаю отличить по хорошему можно только INSERT от DELETE, отличить их обеих от UPDATE представляется сложным (для сервера), потому что они являются частью, то есть UPDATE таблицы с триггером равен последовательным DELETE и INSERT. Вот не помню статью в BOL где написано когда UPDATE делается in-place, а когда через DELETE-INSERT, но помню, что наличие триггера автоматически переводит его на второй способ. Спасибо за внимание. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.03.2002, 12:25 |
|
||
|
Каскады в триггерах, Исполнение триггера до и после операции.
|
|||
|---|---|---|---|
|
#18+
Большое всем спасибо. Очень был рад, что так оперативно все кто мог что-то сказать откликнулись. Чтобы не отнимать более вашего времени вопрос снимаю. Если что-то кардинально новое есть то пожалуйста продолжайте. Я понял что в MSSQL несколько другая логика работы с базой, все в основном через рассмаривается через призму UPDATE = DELETE -> INSERT. Отсюда нужна и несколько другая логика мышления. Еще раз спасибо. Сергей. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.03.2002, 14:25 |
|
||
|
|

start [/forum/topic.php?fid=46&fpage=3498&tid=1823663]: |
0ms |
get settings: |
9ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
37ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
| others: | 289ms |
| total: | 428ms |

| 0 / 0 |
