列'AuctionStatus'不能在IF UPDATE子句中使用,因为它是计算列

时间:2012-03-22 12:41:35

标签: asp.net sql-server

我正在开发asp.net3.5和sql server 2008R2的拍卖网站,我的数据库有一个拍卖表,其计算列为“AuctionStatus” - ([EndDateTime]< getdate()然后'0'否则'1'结束时的情况) 根据结束日期提供拍卖状态有效或无效。

现在我想调用一个存储过程,一旦AuctionStatus变为'0',就会向买家和卖家发送电子邮件通知。为此,我试图创建一个可以调用电子邮件通知sp的更新后触发器,但我无法这样做。 我收到以下错误消息: -

  

Msg 2114,Level 16,State 1,Procedure trgAuctionEmailNotification,   第6行列'AuctionStatus'不能在IF UPDATE子句中使用   因为它是一个计算列。

触发器是:

CREATE TRIGGER trgAuctionEmailNotification ON SE_Auctions
AFTER UPDATE
AS
BEGIN
    IF (UPDATE (AuctionStatus))

BEGIN

 IF EXISTS (SELECT * FROM inserted WHERE currentbidderid > 0
                                      AND AuctionStatus='0' )
     BEGIN
        DECLARE @ID int
        SELECT @ID = AuctionID from inserted
        EXEC spSelectSE_AuctionsByAuctionID @ID         
     END
    END
END

2 个答案:

答案 0 :(得分:0)

您可以将AuctionStatus替换为相应的表达式:

IF EXISTS (SELECT * FROM inserted WHERE currentbidderid > 0 AND [EndDateTime] < getdate() )

但是,重点是我看不到你的触发器将如何被“触发”,因为[AuctionStatus]永远不会“更新”。它的价值只在您需要时计算。

您可以选择每隔x分钟运行一次的sql作业,并为最近x分钟内结束的每次拍卖发送通知。

答案 1 :(得分:0)

您需要添加一个包含标志的实际列,以指示是否已发送通知,然后实施轮询技术以扫描表中状态为非活动且尚未发送通知的行。

计算列并没有真正从一种状态转换到另一种状态,因此它不像UPDATE那样。即使SQL Server确实实现了这一点,它也会非常昂贵,因为它必须每隔3ms查询整个表以转换行。 (如果您使用datetime2具有更高的精度,则更频繁地使用)

您可以自己选择合适的轮询间隔。这可能是一个SQL代理作业,或者在某个地方的某些服务代码中,最适合您架构的其他部分。