После удаления срабатывает только после удаления? - PullRequest
1 голос
/ 05 мая 2010

Я думал, что "после удаления" означало, что триггер не срабатывает до тех пор, пока удаление не произойдет, но вот моя ситуация ...

Я сделал 3, почти идентичных SQL CLR после триггеров удаления в C #, которые прекрасно работали около месяца. Внезапно один из трех перестал работать, когда на нем был запущен инструмент автоматического удаления.

Перестав работать, я имею в виду, записи не могут быть удалены из таблицы через клиентское программное обеспечение. Отключение триггера приводило к тому, что удаление разрешалось, но повторное включение мешало возможности удаления.

Итак, мой вопрос: как это может быть? Возможно ли, что инструмент, используемый на нем, уничтожил память? Похоже, даже если триггер сгенерировал исключение, если это ПОСЛЕ удаления, разве записи не должны исчезнуть?

Все триггеры выглядят так:

ALTER TRIGGER [sysdba].[AccountTrigger] ON [sysdba].[ACCOUNT]  AFTER  DELETE AS 
EXTERNAL NAME [SQL_IO].[SQL_IO.WriteFunctions].[AccountTrigger]
GO

Триггер CLR делает один выбор и одну вставку в другую базу данных. Я еще не знаю, есть ли какие-либо ошибки в SQL Server Mgmt Studio, но обновлю вопрос после того, как узнаю.

UPDATE:

Хорошо после повторного выполнения того же кода триггера, описанного выше, все работает снова, поэтому я никогда не узнаю, что произойдет, если возникнет какая-либо ошибка SSMS.

Кроме того, нигде в коде триггера нет вызова для отката.

Ответы [ 3 ]

6 голосов
/ 05 мая 2010

после означает, что он просто срабатывает после события, его все еще можно откатить

пример

create table test(id int)
go


create trigger trDelete on test after delete
as

print 'i fired '
rollback

сделать вставку

insert test values (1)

теперь удаляем данные

delete test

Вот выход из триггера

я уволил

Сообщение 3609, Уровень 16, Состояние 1, Строка 1

Транзакция завершилась в триггере. Пакет был прерван.

Теперь проверьте таблицу и убедитесь, что ничего не было удалено

select * from test

Триггер CLR делает один выбор и одна вставка в другую базу данных. я пока не знаю, есть ли ошибки из SQL Server Mgmt Studio, но будет обновите вопрос после того, как я узнаю.

Внезапно один из трех остановился работая в то время как инструмент автоматического удаления был запущен на нем.

запускает срабатывание для каждой серии / оператора, а не для строки. Возможно ли, что ваш триггер не был закодирован для многострочных операций, а автоматизированный инструмент удалил более 1 строки в пакете? Взгляните на Рекомендация: кодирование триггеров SQL Server для многострочных операций

Вот пример, который приведет к сбою триггера без явного отката

alter trigger trDelete on test after delete
as

print 'i fired '
declare @id int
select @id = (select id from deleted)
GO

вставить несколько строк

insert test values (1)
insert test values (2)
insert test values (3)

запустите это

delete test

я уволен Сообщение 512, Уровень 16, Состояние 1, Процедура trDelete, Строка 6

Подзапрос вернул более 1 значения. Это недопустимо, если подзапрос следует =,! =, <, <=,>,> = Или когда подзапрос используется в качестве выражения.

Оператор был расторгнут.

проверить таблицу

select * from test

ничего не удалено

1 голос
/ 05 мая 2010

Что ж, вы не должны делать выбор в триггере (который будет видеть результаты), и если все, что вы делаете, это вставка, то это также не должен быть триггер CLR. CLR обычно не очень хорошая вещь в триггере, гораздо лучше использовать код t-SQL в триггере, если вам не нужно делать что-то, что t-sql не может обработать, что, вероятно, в любом случае является плохой идеей в триггере.

Вы вернулись к последней версии, которая у вас есть в системе контроля версий? Возможно, это решило бы проблему, если бы она была повреждена.

1 голос
/ 05 мая 2010

Ошибка в триггере AFTER DELETE приведет к откату транзакции. Это после того, как они удалены, но до того, как изменение будет зафиксировано. Есть ли какая-то особая причина, по которой вы используете для этого триггер CLR? Похоже, что триггер на чистом SQL должен быть в состоянии сделать его более легким способом.

...