我有一张 table ,不知何故,同一个人两次进入我的 Person
表。现在,主键只是一个自动编号,但还有其他两个字段我想强制它们是唯一的。
例如,字段是:
ID
Name
Active
PersonNumber
我只需要 1 条具有唯一 PersonNumber 且 Active = 1 的记录。
(所以两个字段的组合需要唯一)
在 SQL Server 中的现有表上最好的方法是什么?我可以做到这一点,这样如果其他人使用与现有值相同的值进行插入,它就会失败,所以我不必在我的应用程序中担心这个问题代码。
最佳答案
删除重复项后:
ALTER TABLE dbo.yourtablename
ADD CONSTRAINT uq_yourtablename UNIQUE(column1, column2);
或
CREATE UNIQUE INDEX uq_yourtablename
ON dbo.yourtablename(column1, column2);
当然,在让 SQL Server 尝试插入行并返回异常(异常的代价很高)之前,首先检查是否存在这种违规通常会更好。
如果您想防止异常冒泡到应用程序,而不对应用程序进行更改,则可以使用 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
最后插入时出现错误消息:
Msg 2627, Level 14, State 1, Line 3 Violation of UNIQUE KEY constraint 'uq_Person'. Cannot insert duplicate key in object 'dbo.Person'. The statement has been terminated.
此外,我最近在博客中介绍了一种将唯一约束应用于以任一顺序的两列的解决方案:
关于sql - 为两列的组合添加唯一约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15800250/