Транзакция закончилась триггером. Партия была прервана. Полученный атрибут
-
26-10-2019 - |
Вопрос
У меня есть этот триггер:
CREATE trigger [dbo].[DeriveTheAge] on [dbo].[Student]
after insert,update
as
begin
declare @sid as int;
declare @sdate as date;
select @sid= [Student ID] from inserted;
select @sdate=[Date of Birth] from inserted;
commit TRANSACTION
if(@sdate is not null)
begin
update Student set Age=DATEDIFF(YEAR,@sdate,GETDATE()) where [Student ID]=@sid;
end
print 'Successfully Done'
end
Как предполагает, триггер автоматически рассчитывает полученный атрибут «возраст» с даты рождения. Но я получаю эту ошибку, когда делаю вставку:
(1 row(s) affected)
Successfully Done
Msg 3609, Level 16, State 1, Line 1
The transaction ended in the trigger. The batch has been aborted.
Первоначально я избегал этой ошибки, потому что строки получали обновление, несмотря на ошибку. Но теперь, когда я вставляю запись из конца Fornt, запись не обновляется. Вместо этого он бросает это исключение:
Кто -нибудь может мне помочь?
Кстати, Mine - это SQL Server 2008 R2 и Visual Studio 2010.
Коррекция : Записи все еще обновляются. Но исключением является Вилан.
Обновлять
CREATE TRIGGER [dbo].[DeriveTheAge]
ON [dbo].[Student]
FOR INSERT, UPDATE
AS
BEGIN
UPDATE s
SET Age = DATEDIFF(YEAR, [Date of Birth], CURRENT_TIMESTAMP)
FROM dbo.Student AS s
INNER JOIN inserted AS i
ON s.[Student ID] = i.[Student ID]
WHERE i.[Date of Birth] IS NOT NULL;
commit transaction
END
GO
Решение
Почему вы совершаете триггер? Почему вы не обрабатываете много рядовые вставки или обновления? Вы не можете просто объявить переменные и назначить их из вставленных - какие значения, по вашему мнению, будут назначены, когда вы обновляете 2 или 15 или 6000 строк?
CREATE TRIGGER [dbo].[DeriveTheAge]
ON [dbo].[Student]
FOR INSERT, UPDATE
AS
BEGIN
UPDATE s
SET Age = DATEDIFF(YEAR, [Date of Birth], CURRENT_TIMESTAMP)
FROM dbo.Student AS s
INNER JOIN inserted AS i
ON s.[Student ID] = i.[Student ID]
WHERE i.[Date of Birth] IS NOT NULL;
END
GO
Все сказано, почему вам понадобится спусковой крючок, чтобы рассчитать чей -то возраст? Вы можете получить это с даты рождения прямо сейчас в запросе времени и знать, что это будет точным, в отличие от этого устаревшего значения, которое вы сохранили в таблице. Обратите внимание, что если их строка не обновляется более года, возраст, который вы поместили в таблице, устарел. Когда вы вернетесь и обновляете возраст для всех рядов в таблице? Один раз в день? Все, что меньше, и ваша возрастная колонка совершенно ненадежно и бессмысленно.
Также, DATEDIFF(YEAR
не является надежным способом рассчитать возраст в первую очередь. Все, что он делает, - это считать количество границ, которые были пересечены, он понятия не имеет, не является ли фактический день рождения человека 1 января или 31 декабря или где -либо между ними.
Наконец, я бы не печатал с триггера. Кто будет потреблять это печатное заявление, когда вы не отладки?