po_saa Ответов: 1

Откат транзакции в триггере


Я имел в виду, чтобы оценить и откатить, если не соответствует строке таблицы

создание и заполнение таблицы

Use Test
go

if OBJECT_ID('ttable','U') is not null
	drop table ttable
go

declare @jj nvarchar(MAX) = N'[
{"text":"10","f_date":"1/11/20"},
{"text":"11","f_date":"1/11/21"},
{"text":"12","f_date":"1/11/22"}]';

select * into ttable from OPENJSON(@jj) with ([text] nvarchar(50),f_date smalldatetime)


и триггер для каждой вставки и обновления

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE or alter TRIGGER dbo.TTest 
   ON dbo.ttable
   AFTER INSERT, UPDATE
AS 
BEGIN
	SET NOCOUNT ON;
	declare @txt nvarchar(50);  

	set @txt = (select [text] from inserted);
if @txt != '333'
	begin
		RAISERROR ('%s Not equal 333', 16, 1, @txt) with nowait;
			rollback TRANSACTION;  
	END
end
GO


заполните таблицу некоторыми записями

insert into ttable values('2','1/1/12')
insert into ttable values('3','1/1/13')
insert into ttable values('4','1/1/14')
insert into ttable values('5','1/1/15')
insert into ttable values('6','1/1/16')
insert into ttable values('7','1/1/17')
insert into ttable values('8','1/1/18')
insert into ttable values('9','1/1/19')


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

но триггер оценивает только то, что первый запись и блокирует обработку остальных строк

Не могли бы вы мне помочь

Что я уже пробовал:

TSQL, MSDN, C#, инструкция ROLLBACK Transaction (Transact-SQL)[^]

Richard Deeming

NB: Триггеры могут и будут срабатывать с несколькими строками в inserted стол. Ваш триггер должен обрабатывать этот случай; в настоящее время он просто проверяет текст из последней вставленной/обновленной строки.

po_saa

Привет, Ричард!
Инструкции raiserror бросает исключение на попробовать\поймать.
Мне было любопытно - как обрабатывать вставки одну за другой с помощью триггерной оценки
и отклонить не совпадающие строки

Richard Deeming

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

Если вы хотите вставить соответствующие строки, то вам нужно будет вставить каждую строку в свой собственный пакет. В среде SQL Server Management Studio поместите GO между каждым из них INSERT линия:

insert into ttable values (...)
GO
insert into ttable values (...)
GO
...

po_saa

да!
Я читал MSDN по этой теме.
В противном случае откат отменяет остальную часть пакета

1 Ответов

Рейтинг:
1

Gerry Schmitz

Вы пропустили часть о "начале транзакций".

НАЧАТЬ ТРАНЗАКЦИЮ (Transact-SQL) - SQL Server | Microsoft Docs[^]