交易以触发结束.批次已中止.派生属性

Kam*_*ron 2 sql-server triggers derived visual-studio-2008

我有这个触发器:

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
Run Code Online (Sandbox Code Playgroud)

如它所示,触发器会自出生日期起自动计算派生属性"年龄".但是当我执行插入操作时出现此错误:

(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.
Run Code Online (Sandbox Code Playgroud)

最初我避免了这个错误,因为尽管出现错误,行仍在更新.但是现在当我从FORNT END插入记录时,记录不会更新.相反,它会抛出此异常:在此输入图像描述

有人可以帮帮我吗?

顺便说一句,我的是SQL Server 2008 R2和Visual Studio 2010.

更正:记录仍在更新中.但是例外是Vilan.

更新

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
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 8

你为什么要投入扳机?为什么不处理多行插入或更新?您不能只声明变量并从插入中分配它们 - 您认为在更新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
Run Code Online (Sandbox Code Playgroud)

这一切都说,为什么你需要一个触发器来计算某个人的年龄?您可以在查询时从出生日期开始计算,并知道它是准确的,不像您存储在表中的这个陈旧值.请注意,如果他们的行未更新超过一年,则您放入表中的年龄已过期.你什么时候回去更新表中所有行的Age?一天一次?少一点,你的年龄栏完全不可靠和毫无意义.

此外,DATEDIFF(YEAR首先不是计算年龄的可靠方法.它所做的只是计算已经越过的年份边界的数量,它不知道该人的实际生日是1月1日或12月31日还是介于两者之间的任何地方.

最后,我不会从触发器打印出来.当你没有调试时,谁会使用那个print语句?