【问题标题】:Trigger recognising data as duplicates when it isn't触发将数据识别为重复数据而不是重复数据
【发布时间】:2017-07-18 15:52:00
【问题描述】:

我在 SQL Server 中有这个触发器:

CREATE TRIGGER MyTrigger ON [dbo].[practiseduplicates]   
AFTER INSERT
AS
    IF EXISTS (SELECT * 
               FROM [practiseduplicates] t 
               INNER JOIN inserted i ON i.[money] = t.[money] 
                                     AND i.[Name] = t.[Name] 
                                     AND i.[year month] = t.[year month])
    BEGIN
        ROLLBACK
        RAISERROR ('Duplicated Data', 16, 1);
    END

然后我插入这些值(已经在数据表中):

insert into [practiseduplicates]
values ('2017-02', 'buzzlightyear', '10.09')

当我单击执行时,我预计会弹出错误消息...确实如此,但是当我将值更改为我知道不在数据表中的信息时

例如

'2056-12', 'mr potato head', '12345.09'

还是会弹出错误信息,其实应该是刚刚将数据插入到表中,有谁知道为什么会这样吗?

我怀疑这与我的内部连接语句有关,但我不确定。

【问题讨论】:

  • 我希望这是一个关于触发器练习的学习,因为保持重复是唯一约束的工作。
  • 与其说是触发练习,不如说是避免重复。所以我猜我现在使用了错误的技术?
  • 是的,错误的技术。

标签: sql-server triggers duplicates inner-join rollback


【解决方案1】:

引用你的问题

当我单击执行时,我预计会弹出错误消息...确实如此,但是当我将值更改为我知道不在数据表中的信息时

语句的斜体部分不太准确,因为即使这些值之前不在表中,在您运行插入之后,它们也在那里。触发器将触发。

简而言之,您正在创建一个 AFTER INSERT 触发器并检查插入到表中的数据是否已经在表中(运行插入后)。当然,触发器每次都会触发,因为如果数据在插入的表中,它就在表中(因为它是刚刚插入的)。

【讨论】:

  • 我明白了,那么什么是正确的技术,上面的香农提出了一个独特的约束?
  • 根据您发布的内容,是的,对这 3 列的唯一约束似乎可以在该表上执行您想要的操作(前提是到目前为止没有任何重复项)。
【解决方案2】:

所以基本上我使用约束而不是触发器语句来解决这个问题。

ALTER TABLE [dbo].[practiseduplicates]    
ADD CONSTRAINT [constraintforduplicates] UNIQUE NONCLUSTERED
( [column name],
[column name], etc etc
)

这会使用您在约束语句中声明的列作为要比较的数据来停止任何重复,并标记它们是否重复并且不会将数据插入到表中。

请注意,语句中的列本身具有 900 字节的约束。因此,例如,如果您有 varchar (max) 列,则约束将不会运行,因为它可以执行的最大值为 900 字节。在我的脚本中,我输入了 varchar (800)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-30
    • 2014-09-21
    • 2019-06-20
    • 1970-01-01
    • 2014-07-04
    相关资源
    最近更新 更多