使更多列数据唯一的约束

constraint to make further column data unique

我有一个 table 和一些数据。现在,我想将非唯一列设置为唯一列。 但问题是,我不想删除 table 中存在的重复数据,而是想限制要添加到 table 中的数据不唯一。

实用: 我有一个 table tbl,其中 name,age 作为列。 我在 table 中有如下数据:

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

现在我想让名称列唯一,而不删除 'mohan' 和 'karthik' 的重复条目。

如何写这样的约束

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

中的其他记录

假设您有一个名为 id:

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

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

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

这将使您能够在 table 上保持其他名称的唯一性 - 但是,它不会阻止您为任何现有名称再插入一个副本 - 因此您可以插入另一个 mohan或另一个 kumar 到 table(但只有一个)。

如果要排除所有重复项,包括现有行的重复项,最好的选择可能是使用 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