2013-02-14 114 views
0

我有一个SQL触发如下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 

如果我是正确的按触发的/插入的每一条记录时触发运行时,它会检查一年的到期日期栏更新并且如果该值小于1971,那么它将用更新查询中的日期更新它。

奇怪的是它不按预期工作。

if条件似乎不起作用。

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

+0

您发现任何错误 – user2001117 2013-02-14 05:10:36

+0

没有错误。 if条件始终使用第一个插入或更新的列的到期日期,并用于检查记录的其余部分。 – ckv 2013-02-14 05:14:15

+0

ExpirationDate存储日期时间或日期.Year可以采用日期参数并使用我的代码尝试一次 – user2001117 2013-02-14 05:19:43

回答

3

- 肯定有某种根本性错误,你写了这个触发的方式。 SQL Server(假设这就是你正在使用的)将触发触发器不是每行一次(包括你自己在内的许多人)似乎认为 - 触发器被触发每批次可能更新或插入10, 20,50行一次。

因此,触发内Inserted伪表可以(!)包含多个行 - 在这种情况下 - 究竟是你的说法在这里选择?

Select @expDate = inserted.ExpirationDate from inserted 

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

您需要要记住你的触发器 - 你必须总是假设Inserted(和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语法(表的逗号分隔的列表)的ANSI标准,一直在地方自1992年起 - 请不要使用表的逗号分隔的列表使用适当 ANSI连接看到这个博客帖子的更多背景资料:Bad habits to kick : using old-style JOINs

+0

感谢您的回答。我想我明白了。 – ckv 2013-02-26 07:09:34

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 
+0

我试过这个,但结果仍然相同。 – ckv 2013-02-14 05:23:50

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 
+0

这是行不通的 - 你也假定'Inserted'只包含一行 - 这不是这种情况!你在这里选择什么:如果你的触发器触发一行50行的插入,并且'Inserted'包含50行,选择@expDate = inserted.ExpirationDate from inserted' – 2013-02-14 06:28:46