首页 > 解决方案 > 使进一步的列数据唯一的约束

问题描述

我有一张包含一些数据的表格。现在,我想将非唯一列设为唯一。但问题是,我不想删除表中存在的重复数据,但想限制要添加到表中的数据不唯一。

为了实用:我有一个表 tbl 名称,年龄作为列。我在表中的数据如下:

name      |age
-----------------------
kaushikC  |21
mohan     |27
kumar     |29
mohan     |31
karthik   |55
karthik   |76

现在我想使名称列唯一而不删除“mohan”和“karthik”的重复条目。

如何编写这样的约束

标签: sqlsql-serversql-server-2008

解决方案


如果您的表中有一个列允许您识别不想更改的记录,例如identity列或创建日期,您可以在表上创建一个唯一的过滤索引,在它的where子句中指定它应该只包括表中的其他记录。

假设您有一个identity名为 的列id

id | name      |age
-----------------------
1  | kaushikC  |21
2  | mohan     |27
3  | kumar     |29
4  | mohan     |31
5  | karthik   |55
6  | karthik   |76

您可以在此表上创建一个唯一过滤索引,该索引仅对id大于 6 的行有效:

CREATE UNIQUE INDEX UX_YourTable_Name_WhereIdGraterThanSix   
   ON YourTable (Name)
   WHERE id > 6;   

这将使您能够保持表上其他名称的唯一性 - 但是,它不会阻止您为任何现有名称插入一个更多重复项 - 因此您可以将另一个mohan或另一个插入kumar到表中(但只有一个)。

如果要排除所有重复项,包括现有行的重复项,最好的选择可能是使用instead of触发器进行插入和更新:

CREATE TRIGGER tr_YourTable ON YourTable
INSTEAD OF INSERT, UPDATE
AS
BEGIN
    -- the statement that fired the trigger is an update statement
    IF EXISTS(select 1 FROM deleted) 
    BEGIN
        UPDATE T
        SET name = I.Name
        FROM YourTable AS T
        JOIN Inserted AS I 
            ON T.Id = I.Id
        WHERE NOT EXISTS
        (   -- make sure the name is unique
            SELECT 1
            FROM YourTable AS T1
            WHERE T1.Name = I.Name
            AND NOT EXISTS
            (   -- unless it is going to be updated
                SELECT 1
                FROM Deleted AS D
                JOIN Inserted AS I
                    ON D.Id = I.Id
                WHERE D.Id = T1.Id
                AND T1.Name = D.Name
                AND D.Name <> I.Name 
            )
        )
    END
    ELSE -- the statement that fired the trigger is an insert statement
    BEGIN 
        INSERT INTO YourTable(Name)
        SELECT I.Name
        FROM Inserted I
        WHERE NOT EXISTS
        (   -- make sure the name is unique
            SELECT 1
            FROM YourTable AS T1
            WHERE T1.Name = I.Name
        )
    END
END

推荐阅读