使用触发器删除回滚时的最后一次插入

时间:2015-03-21 17:21:37

标签: sql sql-server triggers

当我在表中插入三行时,我有这个触发器,检查三行的总和是否等于10,否则就完成了回滚。问题是此触发器仅在尝试插入第三行时触发,这意味着插入前两行。但是现在我想改变这个触发器,这样如果总和不是三行中的10个,我希望删除插入的两个第一行。有谁知道如何更改触发器,以便删除最后插入的两行?

当前触发码:

ALTER TRIGGER [dbo].[trg_Sum] ON [dbo].[Table]
AFTER UPDATE, INSERT
AS

IF EXISTS (
SELECT TOP 1 NULL FROM (
SELECT SUM(Procentandel) AS Sum
FROM Table
WHERE    
      ID = (SELECT ID FROM inserted) 
AND 
      ID2 = (SELECT ID2 FROM inserted)
GROUP BY ID, ID2
HAVING COUNT(*) = 3) t
WHERE t.Sum <> 10
)

BEGIN
RAISERROR ('The sum must be 10!',16, 1)
ROLLBACK TRANSACTION
END

2 个答案:

答案 0 :(得分:0)

以下触发器将保持不变量“没有id1和id2的组合恰好有三行不总和为10”。

create trigger dbo.trg_sum on dbo.trigger_test after update, insert as
delete
    t
from
    dbo.trigger_test t
where exists (
    select
        'x'
    from
        dbo.trigger_test t2
    where
        t.id1 = t2.id1 and 
        t.id2 = t2.id2 and
        exists (
            select
                'x'
            from
                inserted i
            where
                i.id1 = t2.id1 and
                i.id2 = t2.id2
        )
    group by
        t2.id1,
        t2.id2
    having
        count(*) = 3 and
        sum(t2.Procentandel) != 10
);

要了解为什么以基于集合的方式完成,请考虑以下语句:

insert into dbo.trigger_test (
    Id1, Id2, Procentandel
) values 
    (1, 1, 1),
    (1, 1, 1),
    (1, 1, 1);

insert into dbo.trigger_test (
    Id1, Id2, Procentandel
) values 
    (1, 1, 1);

insert into dbo.trigger_test (
    Id1, Id2, Procentandel
) values 
    (1, 1, 1),
    (1, 1, 1);

那就是说,触发器感觉就像是错误的设计。它似乎更像是一个有三列的表,每个值槽一个更容易。

答案 1 :(得分:0)

假设您所指的所有3行都在同一个交易中被修改,您可以这样做:

ALTER TRIGGER [dbo].[trg_Sum] ON [dbo].[Table]
AFTER UPDATE, INSERT
AS

IF (SELECT SUM(Procentandel) FROM inserted) <> 10)
BEGIN
RAISERROR ('The sum must be 10!',16, 1)
ROLLBACK TRANSACTION
END