TSQL делают триггерный сбой тихо

У меня есть некоторый код в после того, как вставляют триггер, который может потенциально перестать работать. Такой отказ не крайне важен и не должен откатывать транзакцию. Как я могу захватить ошибку в триггере и иметь остальную часть транзакции, обычно выполняются?

Пример ниже показывает то, что я имею в виду. Триггер намеренно создает состояние ошибки, так что в итоге исходная вставка ("1") никогда не вставляет в таблицу. Попытка/Выгода, казалось, не добивалась цели. Подобный, более старый вопрос о переполнении стека не уступил, ответ за исключением "препятствуют ошибке произойти во-первых" - который не всегда возможен/легок.

Какие-либо другие идеи?

create table test 
(
  a int not null
);
go

create trigger testTrigger on test 
after insert as 
begin 
  insert into test select null;
end;
go

insert into test values ( 1 );

6
задан Community 23 May 2017 в 11:59
поделиться

2 ответа

Из-за того, как триггеры реализованы в SQL Server , все нарушения ограничения в триггерах обдумывают транзакции.

Это то же самое, что делает:

DROP TABLE test

CREATE TABLE test 
(
        a INT NOT NULL
)

GO

SET XACT_ABORT ON
GO

BEGIN TRANSACTION

BEGIN TRY
        INSERT
        INTO    test
        SELECT  NULL
END TRY
BEGIN CATCH
        INSERT
        INTO    test
        SELECT  1
END CATCH

, который приводит к обреченной транзакции, за исключением того, что нет способа отключить xact_abort внутри триггера.

SQL Server также не хватает автономных транзакций.

Это еще одна причина, по которой вы должны поставить всю логику в хранимые процедуры, а не триггеры.

1
ответ дан 17 December 2019 в 18:16
поделиться

Спусковой механизм не может отказать, и все равно происходит откат транзакции. У вас есть несколько вариантов, чтобы гарантировать, что триггер не сработает.

1 - Вы можете гарантировать, что триггер не даст сбой, дублируя логику проверки ограничений и не пытаясь выполнить операцию, которая нарушит ограничения:

т.е.

INSERT INTO test WHERE val IS NOT NULL

2 - Вы можете отложить потенциально неудачное действие, используя шаблон построения очереди, в которой действия, которые могут или не могут дать сбой, ставятся в очередь, путем вызова таблицы, в которой операция вызова не может дать сбой.

, т.е.

INSERT INTO ACTION_QUEUE (action, parameters) VALUES ('INSERT INTO TEST', val)
2
ответ дан 17 December 2019 в 18:16
поделиться
Другие вопросы по тегам:

Похожие вопросы: