删除重复项后:
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
要么
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
当然,通常最好先检查此冲突,然后再让SQL Server尝试插入行并返回异常(异常昂贵)。
http://www.sqlperformance.com/2012/08/t-sql-queries/error-handling
http://www.mssqltips.com/sqlservertip/2632/checking-for-potential-constraint-violations-before-entering-sql-server-try-and-catch-logic/
如果要防止异常在应用程序中冒泡,而又不对应用程序进行更改,则可以使用INSTEAD OF
触发器:
CREATE TRIGGER dbo.BlockDuplicatesYourTable
ON dbo.YourTable
INSTEAD OF INSERT
AS
BEGIN
SET NOCOUNT ON;
IF NOT EXISTS (SELECT 1 FROM inserted AS i
INNER JOIN dbo.YourTable AS t
ON i.column1 = t.column1
AND i.column2 = t.column2
)
BEGIN
INSERT dbo.YourTable(column1, column2, ...)
SELECT column1, column2, ... FROM inserted;
END
ELSE
BEGIN
PRINT 'Did nothing.';
END
END
GO
但是,如果您不告诉用户他们没有执行插入操作,他们会想知道为什么数据不存在并且没有报告异常。
这里的“ 编辑”是一个示例,它可以完全满足您的要求,甚至使用与您的问题相同的名称,也可以对其进行证明。您应该先尝试一下,然后再假设上述想法只处理一栏或另一栏,而不是结合使用...
USE tempdb;
GO
CREATE TABLE dbo.Person
(
ID INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(32),
Active BIT,
PersonNumber INT
);
GO
ALTER TABLE dbo.Person
ADD CONSTRAINT uq_Person UNIQUE(PersonNumber, Active);
GO
-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
-- succeeds:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 0, 22);
GO
-- fails:
INSERT dbo.Person(Name, Active, PersonNumber)
VALUES(N'foo', 1, 22);
GO
所有这些之后,表中的数据:
ID Name Active PersonNumber
---- ------ ------ ------------
1 foo 1 22
2 foo 0 22
最后插入的错误消息:
消息2627,级别14,状态1,第3行违反UNIQUE KEY约束'uq_Person'。无法在对象“ dbo.Person”中插入重复密钥。该语句已终止。