【问题标题】:Why does my trigger to avoid duplicate rows not work?为什么我的避免重复行的触发器不起作用?
【发布时间】:2017-10-04 00:59:37
【问题描述】:

在有人建议唯一索引或键之前,我有一个很好的例子。

我正在使用这个触发器,来自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]

【问题讨论】:

  • Scott 对该答案的评论包含一条关键信息 - 您需要确保 inserted 中的行 匹配 它们自己在表中(由于这是for/after 触发器,插入的行已经在表中)

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


【解决方案1】:

发生这种情况是因为它正在检测您当前插入到表中的记录。您需要从 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

【讨论】:

  • 好的,谢谢。我确实对插入后已经存在的记录有些怀疑,但在我吵着要答案时,PK 的想法让我望而却步。
【解决方案2】:

无论如何,建议约束

ALTER TABLE bkPersonPoints
  ADD CONSTRAINT c_uniq_Name_and_points UNIQUE (Name, Points)

【讨论】:

  • 字面意思问题的第一行开始于“在任何人建议唯一索引或键之前...”
  • 最好不要使用旨在处理这种确切情况的特定数据库功能......
  • @Damien_The_Unbeliever 是的,但我想,没有必要使用触发器来检查唯一性,所以我建议:3
  • 我的用例是最重要的,不一定只是防止插入记录,而是记录潜在的重复,并希望能了解导致重复插入的原因。我什至可能不需要阻止插入,而只需将重复项的数量归零。除了阻止插入之外,唯一键对于任何其他操作都是无用的。
【解决方案3】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-03-29
    • 2017-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多