【问题标题】:T-SQL - anti-duplicate triggerT-SQL - 反重复触发器
【发布时间】:2015-07-23 23:47:46
【问题描述】:

我需要编写一个触发器来防止同时插入多个记录,并检查该位置是否已经在数据库中。代码可以编译,但不能正常工作 - 即使我尝试添加不存在的地址,它也会显示错误消息

这是我的代码:

CREATE TRIGGER address_duplicate ON place
AFTER INSERT
AS
BEGIN
	DECLARE @counter INT
	SELECT @counter=COUNT(*) FROM place WHERE street IN (SELECT street FROM inserted) AND number IN(SELECT number FROM inserted)
	AND city IN(SELECT city FROM inserted) AND postcode IN(SELECT postcode FROM inserted)
	IF @counter>0
	BEGIN
	RAISERROR('This record is already in the database',1,1)
	ROLLBACK
	END
	IF @@ROWCOUNT>1
	BEGIN
	RAISERROR('You can add only one record at the same time',1,2)
	ROLLBACK
	END
END
GO

【问题讨论】:

  • 目前尚不清楚导致这种情况的逻辑是什么,但我认为唯一索引会比触发器容易得多。
  • 在重复项上,为什么不添加唯一约束。阻止用户在语句中插入多个插入解决了什么问题。它们只能有多个插入语句。
  • 您可能想要检查INSERTUPDATE 上的重复项。如果您不需要特定的重复次数,您应该使用EXISTS。在重复条件下将 inserted 与您的数据表 (place) 连接,以处理触发器中的多个集合操作(​​多行)。如果有任何失败,它们都会失败。

标签: sql database sql-server-2008 tsql triggers


【解决方案1】:

您识别重复地点的逻辑不正确。

试试这样的:

select @counter= count(*) from place p join inserted n
where p.address=n.address and p.city=n.city and p.postcode=n.postcode 
and p.number=n.number;

还想让您知道,使用触发器来避免重复可能非常昂贵。

【讨论】:

    【解决方案2】:

    就个人而言,我会使用唯一约束,并且在插入时可能会使用 TRY-CATCH,但如果您真的想在触发器中执行此操作,请尝试以下操作:

    CREATE TRIGGER address_duplicate ON place
    INSTEAD OF INSERT
    AS
    BEGIN
        DECLARE @newValue TABLE (ID INT);
    
        IF @@ROWCOUNT > 1
        BEGIN
            RAISERROR('Insert cancelled. You can add only one record at the same time.',1,2);
        END
        ELSE
        BEGIN
            INSERT INTO place
            OUTPUT inserted.ID INTO @newValue
                SELECT *
                FROM inserted
                EXCEPT
                SELECT *
                FROM place
            IF (SELECT 1 FROM @newValue) IS NULL
                RAISERROR('Insert cancelled. This record is already in the database',1,1)
        END
    END
    

    【讨论】:

      猜你喜欢
      • 2013-03-14
      • 2011-06-13
      • 2013-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多