为什么我的触发器避免重复行不起作用?

时间:2017-05-05 13:50:08

标签: sql sql-server tsql triggers sql-server-2012

在任何人建议使用唯一索引或密钥之前,我有一个很好的理由。

我在Trigger to prevent Insertion for duplicate data of two columns

使用此触发器
CREATE TRIGGER LogDuplicates ON bkPersonPoints
FOR INSERT
AS
if exists (select * from bkPersonPoints c 
                    inner join inserted i 
                        on c.Name = i.Name and c.Points = i.Points)
begin
    rollback
end
GO

这个答案被接受并且有15个投票,所以我希望它可以工作,即使在我第一次插入时,也可以进入一个空表:

insert bkPersonPoints (Name, Points) values ('Brady', 100)

我收到错误:

  

交易在触发器中结束。批次已中止。

附录:表格如下所示:

CREATE TABLE [dbo].[bkPersonPoints](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [Points] [int] NOT NULL
) ON [APP_BR2_User]

3 个答案:

答案 0 :(得分:3)

这种情况正在发生,因为它正在检测您当前正在插入表中的记录。您需要从EXISTS子句中过滤掉它:

CREATE TRIGGER LogDuplicates ON bkPersonPoints
FOR INSERT
AS
if exists (select * from bkPersonPoints c 
                    inner join inserted i 
                        on c.Name = i.Name 
                        and c.Points = i.Points
                        and c.id <> i.id)
begin
    rollback
end
GO

答案 1 :(得分:0)

无论如何,建议使用CONSTRAINT

frminst.exe

答案 2 :(得分:0)

<块引用>

此答案的灵感来自于 20 年 4 月 13 日 18:34 在 Trigger to prevent Insertion for duplicate data of two columns 发布的一个答案。

在 dbo.MyTable 上创建触发器 MyTrigger
代替插入
AS

如果不存在(
select * from MyTable t
内连接插入 i
在 i.name=t.name 和 i.date=t.date 和 i.id <> t.id )
开始
插入到 MyTable(名称,日期)中选择名称,插入日期
结束
其他
THROW 51000, '语句终止,因为发现对象重复', 1;

相关问题