0

我有一个如下的 SQL 触发器

GO
create trigger ExpDateCheckCard
On Card 
FOR Insert, Update
As
Declare @expDate as DateTime
Select @expDate = inserted.ExpirationDate from inserted
if (YEAR(@expDate) < 1971 )
BEGIN
     UPdate Card set ExpirationDate = '1900-01-01 00:00:00' FROM Card, inserted
                                where inserted.RecordID = Card.RecordID
END

如果我根据触发器运行时插入/更新的每条记录的触发器是正确的,它将检查该记录的 ExpirationDate 列中的 YEAR,如果该值小于 1971,那么它将使用更新查询中的日期对其进行更新.

奇怪的是它没有按预期工作。

if 条件似乎不起作用。

这个特定的触发器有什么问题。

4

3 回答 3

3

的 - 您编写此触发器的方式肯定存在根本性错误。

SQL Server(假设这是您正在使用的)不会每行触发一次触发器(包括您自己在内的许多人)似乎认为 -每批次触发一次触发器,这可能会一次更新或插入 10、20、50 行.

因此,Inserted触发器内的伪表可以(并且将!)包含多行 - 在这种情况下 - 你的语句在这里选择了什么?

Select @expDate = inserted.ExpirationDate from inserted

要么你只得到一个随机行(50 行)并处理它(并忽略所有其他 49 行),否则你会得到一个错误....

您需要牢记这一点来编写触发器 - 您必须始终假设Inserted(and Deleted) 将包含多行!

因此,您需要将触发器更改为:

CREATE TRIGGER ExpDateCheckCard
ON dbo.Card 
FOR Insert, Update
AS
  UPDATE dbo.Card 
  SET ExpirationDate = '1900-01-01 00:00:00' 
  FROM dbo.Card c
  INNER JOIN inserted i ON i.RecordID = c.RecordID
  WHERE YEAR(i.ExpirationDate) < 1971

我还将您的旧式 JOIN 语法(以逗号分隔的表列表)更改为自 1992 年以来一直存在的 ANSI 标准 - 请不要使用以逗号分隔的表列表!使用正确的ANSI JOIN。请参阅此博客文章了解更多背景信息:要踢的坏习惯:使用旧式 JOIN

于 2013-02-14T06:02:47.860 回答
0

试试这个:

create trigger ExpDateCheckCard
    On Card 
    FOR Insert, Update
    As
    BEGIN
    Declare @expDate as DateTime
    Select @expDate = inserted.ExpirationDate from inserted
    if (YEAR(@expDate) < 1971 ) Begin

         UPdate Card set ExpirationDate = '1900-01-01 00:00:00' FROM Card, inserted
                                    where inserted.RecordID = Card.RecordID
    end
    END
于 2013-02-14T05:14:00.140 回答
0

您必须尝试此代码

CREATE TRIGGER ExpDateCheckCard AFTER INSERT,Update ON Card
   FOR EACH ROW

   Declare @expDate as DateTime
   Select @expDate = inserted.ExpirationDate from inserted
   if (YEAR(@expDate) < 1971 )
   BEGIN
      update Card 
      set ExpirationDate = '1900-01-01 00:00:00' FROM Card, inserted
      where inserted.RecordID = Card.RecordID
   END
于 2013-02-14T06:26:21.927 回答