而不是位列上的更新触发器

时间:2017-04-06 14:43:00

标签: sql-server tsql triggers

我有一个小表(下面的代码),其中包含PageKey(int),SendNotification(bit),目前有5个可能的PageKeys。

要求是同时激活不超过1个标志(SendNotification),所以我想创建一个触发器,当有另一个有活动的pageKey时,该触发器不允许将标志更改为True标志。

我编写了以下触发器,但它似乎不起作用。此外,如果您在SQL Server 2012中有任何其他(更好)的解决方案来实现这一点,我会很感激。

CREATE TRIGGER trg_Notification_Flag 
ON dbo.t_Notification_Flag
INSTEAD OF UPDATE
AS
BEGIN 
    SET NOCOUNT ON;

    DECLARE @countOfExistingFlags INT;
    DECLARE @PageKey INT;

    SELECT @countOfExistingFlags = COUNT(*)
    FROM dbo.t_Notification_Flag
    WHERE SendNotification = 1;

    SELECT @PageKey = inserted.PageKey
    FROM inserted;

    IF @countOfExistingFlags > 1
    BEGIN
        PRINT 'There is an existing active flag. No changes has been done.'; 
        ROLLBACK TRANSACTION;
    END;
    ELSE
    BEGIN
        UPDATE dbo.t_Notification_Flag
        SET SendNotification = 1
        WHERE PageKey = @PageKey;
    END;
END;
GO

表是:

CREATE TABLE [dbo].[t_Notification_Flag]
(
    [PageKey] [int] NOT NULL,
    [SendNotification] [bit] NOT NULL,
    [NotificationMessage] [nvarchar](100) NOT NULL,
    [NotificationHeader] [nvarchar](50) NULL,
    [Country_Key] [int] NULL
) ON [PRIMARY]

2 个答案:

答案 0 :(得分:2)

您可以在不触发的情况下实现目标 - 但只需使用过滤后的唯一索引。

类似的东西:

create table dbo.#Temp (PageKey int, Send_Notification bit)
create unique index IX_Temp on dbo.#temp(Send_Notification) where Send_Notification = 1

这将不允许您的表有多个Send_Notification = 1的记录,因此如果您需要为某些记录设置Send_Notification标记 - 您必须先清除它以获取当前记录设置此标志。

答案 1 :(得分:1)

我根本不会使用触发器。相反,我会使用CHECK CONSTRAINT检查UDF,如果没有其他活动标志则返回true,如果有,则返回false。