为两列的组合添加唯一约束

我有一个桌子,不知何故,同一个人进入我的Person表两次。 现在,主键只是一个自动编号,但还有两个其他的字段,我想迫使它们是唯一的。

例如,这些字段是:

 ID Name Active PersonNumber 

我只想要一个唯一的PersonNumber和Active = 1的logging。
(所以这两个领域的组合需要是唯一的)

什么是在SQL服务器现有的表上最好的办法我可以做到这一点,如果任何人做一个插入与现有值相同的值,它会失败,所以我不必担心在我的应用程序代码中的这一点。

一旦你删除了你的副本:

 ALTER TABLE dbo.yourtablename ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2); 

要么

 CREATE UNIQUE INDEX uq_yourtablename ON dbo.yourtablename(column1, column2); 

当然,在让SQL Server尝试插入行并返回一个exception(exception是昂贵的)之前,首先检查这个违规通常会更好。

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/

如果要防止exception冒泡到应用程序,而不更改应用程序,则可以使用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 

但是,如果你不告诉用户他们没有执行插入,他们会想知道为什么数据不在那里,没有例外报告。


编辑这里是一个例子,完全按照你的要求,即使使用相同的名称作为你的问题,并certificate这一点。 你应该尝试一下,假设上述想法只处理一列或另一列,而不是组合…

 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违反唯一键约束“uq_Person”。 不能在对象'dbo.Person'中插入重复的键。 声明已经终止。

这也可以在GUI中完成:

  1. 在“Person”表下,右键单击Indexes
  2. 点击/hover新索引
  3. 点击非聚集索引…

在这里输入图像描述

  1. 将会给出一个默认的索引名称,但您可能想要更改它。
  2. 选中唯一checkbox
  3. 点击添加…button

在这里输入图像描述

  1. 检查你想包括的列

在这里输入图像描述

  1. 在每个窗口中单击确定