Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Определить причину срабатывания триггера  [new]
sraider
Member

Откуда:
Сообщений: 325
Нужно выполнить некоторые действия если обновлено определенное поле в таблице, либо если запись в этой таблице удалена. Можно ли это совместить в одном триггере или нужно делать два триггера, один - after insert, update, второй - after delete?

Если попробовать написать один триггер - проблема в написании условия срабатывания:
create trigger xxx on yyy after insert, update, delete as
if update(fld) or УДАЛЕНИЕ -- как написать проверку на удаление?
print 'делаем что надо'
3 дек 14, 15:10    [16944041]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
если поле есть в inserted И deleted - был апдейт , если толко в deleted -было удаление
3 дек 14, 15:16    [16944083]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
a_voronin
Member

Откуда: Москва
Сообщений: 4804
sraider
Нужно выполнить некоторые действия если обновлено определенное поле в таблице, либо если запись в этой таблице удалена. Можно ли это совместить в одном триггере или нужно делать два триггера, один - after insert, update, второй - after delete?

Если попробовать написать один триггер - проблема в написании условия срабатывания:
create trigger xxx on yyy after insert, update, delete as
if update(fld) or УДАЛЕНИЕ -- как написать проверку на удаление?
print 'делаем что надо'


Внутри триггера есть таблички INSERTED и DELETED , которые обозначают наборы вставленных и удалённых записей. От этих таблиц и отталкивайтесь.

http://www.dotnet-tricks.com/Tutorial/sqlserver/7OT8250912-Inserted,-Deleted-Logical-table-in-SQL-Server.html
3 дек 14, 15:18    [16944094]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
sraider
Member

Откуда:
Сообщений: 325
Maxx,

так?

create trigger xxx on yyy after insert, update, delete as
if update(fld) or (select count(*) from inserted) < (select count(*) from deleted)
print 'делаем что надо'
3 дек 14, 15:21    [16944126]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
sraider,

ну попробуйте...только при операции удаления у вас сие
(select count(*) from inserted) будет NULL со всеми вытекающими последствиями
3 дек 14, 15:24    [16944160]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
sraider
Member

Откуда:
Сообщений: 325
Maxx,

При удалении Count(*) будет 0.
Проверил - при удалении работает как надо.

Меня больше интересует - правильно ли будет работать при Merge. Буду проверять.
3 дек 14, 15:30    [16944195]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
sraider
При удалении Count(*) будет 0.

точно , мой фейл
3 дек 14, 15:38    [16944252]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
sraider,

рекомендую забыть про функцию UPDATE() и сравнивать значения поля в deleted и inserted.
С учётом NULL, разумеется.
Для MERGE не пользуйтесь в триггерах @@ROWCOUNTом.
3 дек 14, 17:58    [16945327]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
sraider
Определить причину срабатывания триггера
Вот, помню, была тема, кстати говоря:
Можно ли в триггере(for U,I,D) определить какое действие над табл. вызвало его?
3 дек 14, 18:03    [16945356]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
Петр К
Member

Откуда:
Сообщений: 53
sraider,

Да можно, конечно. Вы можете написать единый триггер хоть на все три операции: insert, update, delete. (Другое дело, что часто это выходит геморройно и проще разделить обработку). Вот только одной функцией UPDATE() вы тут не обойдетесь. Самое простое: есть у вас некий PK в таблице. Читаете его в триггере в две переменные из системных курсоров deleted и updated. Далее просто: если у вас ключ из deleted пуст (null), а ключ из inserted непуст, то у вас ситуация INSERT; если ключ из deleted непуст, а ключ из inserted пуст - то DELETE, если оба ключа непусты - то UPDATE. С этого момента вы точно знаете, какое событие привело к запуску триггера, и остальной код - дело вашей фантазии :-). PK таблицы использовать проще всего, потому что это поле не может быть пустым (null). Но в принципе годится и любое другое не-null поле.
4 дек 14, 11:13    [16947952]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
Петр К
sraider,

Да можно, конечно. Вы можете написать единый триггер хоть на все три операции: insert, update, delete. (Другое дело, что часто это выходит геморройно и проще разделить обработку). Вот только одной функцией UPDATE() вы тут не обойдетесь. Самое простое: есть у вас некий PK в таблице. Читаете его в триггере в две переменные из системных курсоров deleted и updated. Далее просто: если у вас ключ из deleted пуст (null), а ключ из inserted непуст, то у вас ситуация INSERT; если ключ из deleted непуст, а ключ из inserted пуст - то DELETE, если оба ключа непусты - то UPDATE. С этого момента вы точно знаете, какое событие привело к запуску триггера, и остальной код - дело вашей фантазии :-). PK таблицы использовать проще всего, потому что это поле не может быть пустым (null). Но в принципе годится и любое другое не-null поле.
И чем же это лучше простой проверки наличия записей в deleted/inserted с помощью EXISTS()?
Что вызвало срабатывание триггера, если пусты и deleted и inserted?
4 дек 14, 11:44    [16948204]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
sraider
Member

Откуда:
Сообщений: 325
всем спасибо за информацию!

в итоге остановился на
if update(fld) or (select count(*) from inserted) < (select count(*) from deleted)

этого мне достаточно.

Проверил - при Merge вызывается триггер отдельно на Insert и на Delete, так что одновременно вставки и удаления не будет.
4 дек 14, 15:43    [16950367]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
sraider
всем спасибо за информацию!

в итоге остановился на
if update(fld) or (select count(*) from inserted) < (select count(*) from deleted)


этого мне достаточно.

Проверил - при Merge вызывается триггер отдельно на Insert и на Delete, так что одновременно вставки и удаления не будет.
Количество записей в inserted и deleted всегда либо равно либо что-то из них равно 0.
Что означает Ваша проверка - совершенно непонятною

Какой смысл Вы вкладываете в функцию UPDATE()?
4 дек 14, 15:47    [16950409]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
sraider
Проверил - при Merge вызывается триггер отдельно на Insert и на Delete
А зачем проверять?
Почитать документацию очень трудно, да?
4 дек 14, 15:48    [16950422]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
sraider
Member

Откуда:
Сообщений: 325
iap
Количество записей в inserted и deleted всегда либо равно либо что-то из них равно 0.
Что означает Ваша проверка - совершенно непонятною

Какой смысл Вы вкладываете в функцию UPDATE()?


проверка означает, что триггер вызвался After Delete, и были удалены записи.

в Update() вкладываю смысл - "значение поля fld обновлено". возможно, конечно, что оно было обновлено тем же значением, что и было раньше, но такие случаи будут очень редко (если будут), поэтому ничего что условие в этом случае сработает.
4 дек 14, 17:15    [16951191]     Ответить | Цитировать Сообщить модератору
 Re: Определить причину срабатывания триггера  [new]
iap
Member

Откуда: Москва
Сообщений: 46999
sraider
iap
Количество записей в inserted и deleted всегда либо равно либо что-то из них равно 0.
Что означает Ваша проверка - совершенно непонятною

Какой смысл Вы вкладываете в функцию UPDATE()?


проверка означает, что триггер вызвался After Delete, и были удалены записи.

в Update() вкладываю смысл - "значение поля fld обновлено". возможно, конечно, что оно было обновлено тем же значением, что и было раньше, но такие случаи будут очень редко (если будут), поэтому ничего что условие в этом случае сработает.
Но поле всегда либо получает новое значение либо остаётся со старым.
UPDATE() лишь говорит о том, что какой-то UPDATE "покушался" на это поле в своём SETе.
Однако, многие клиентские программы выполняют UPDATE всех полей (для простоты),
просто "меняя" значения большинства полей на те же, что у них уже есть.
Никакого смысла в применении функции UPDATE() не вижу.

В AFTER DELETE выполняется условие NOT EXISTS(SELECT * FROM inserted),
которое приводит к проверке существования любой единственной записи,
а не к вычислению COUNT(*), как у Вас.
4 дек 14, 17:37    [16951379]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить