【问题标题】:SQL Server UNIQUE constraint with duplicate NULLs [duplicate]具有重复 NULL 的 SQL Server UNIQUE 约束 [重复]
【发布时间】:2010-12-20 06:21:59
【问题描述】:

可能重复:
How do I create unique constraint that also allows nulls in sql server

我有一个表,我需要强制列具有唯一值。 此列必须可以为空,并且根据业务逻辑,应该允许多个 NULL 值,而其他重复值则不允许。

SQL Server UNIQUE 约束在这种情况下不好用,因为它将 NULL 视为常规值,因此它会拒绝重复的 NULL。

目前,值唯一性是由 BLL 授予的,所以我不是在寻找一个肮脏的 hack 来使其工作。 我只是想知道是否有一个干净的解决方案可以在数据库中强制执行此约束。

是的,我知道我可以编写一个触发器来做到这一点:触发器是唯一的解决方案吗? (还是最好的解决方案?)

【问题讨论】:

    标签: sql-server indexing


    【解决方案1】:

    如果您使用的是 SQL Server 2008(不适用于早期版本),则存在筛选索引的概念。您可以在表的过滤子集上创建索引。

    CREATE UNIQUE INDEX indexName ON tableName(columns) INCLUDE includeColumns 
    WHERE columnName IS NOT NULL
    

    【讨论】:

    • 我们使用的是 SQL Server 2008,就这样,谢谢。
    • 这行得通。谢谢!
    • includeColumns 是什么意思/代表什么?
    【解决方案2】:

    this question 的重复?

    计算列技巧被广泛称为“nullbuster”;我的笔记归功于史蒂夫·卡斯:

    CREATE TABLE dupNulls (
    pk int identity(1,1) primary key,
    X  int NULL,
    nullbuster as (case when X is null then pk else 0 end),
    CONSTRAINT dupNulls_uqX UNIQUE (X,nullbuster)
    )
    

    适用于 SQL Server 2000。您可能需要ARITHABORT,例如

    ALTER DATABASE MyDatabase SET ARITHABORT ON
    

    【讨论】:

    • 看起来差不多,发帖前没找到那个问题。无论如何,在这里我们得到了一些关于 TSQL2008“过滤索引”(我什至不知道存在)的好答案,所以我想这是值得重复的 :)
    • 这可能会导致非唯一值 - 考虑dupNulls.pk = 1, X = null && dupNulls.pk = 2, X = 2
    • @Rowland Shaw:用于 dupNulls_uqX UNIQUE 约束的值将是 (NULL, 1) && (2, 0)。我没有看到重复值。
    【解决方案3】:

    您应该在该列中使用 UNIQUEIDENTIFIER,可以为 NULL,并且根据定义也是唯一的。 希望对您有所帮助。

    【讨论】:

    • 我必须将约束应用于 varchar 列,所以我不能使用 UNIQUEIDENTIFIER。
    【解决方案4】:

    【讨论】:

      【解决方案5】:

      如果您使用的是 SQL Server 2008,请查看过滤索引以实现您想要的。

      对于旧版本的 SQL Server,触发器的替代方法可能涉及计算列:

      1. 创建一个计算列,如果它不是 NULL,则使用“唯一”列的值,否则使用行的主键列(或任何唯一列)的值。
      2. UNIQUE 约束应用于计算列。

      【讨论】:

      • 计算列的使用非常有趣。 PK 和实际字段值之间可能存在冲突问题,但带有一些前缀应该可以工作。
      【解决方案6】:

      您可以创建一个只选择非空值并在其上创建索引的视图。

      这里是来源 - Creating Indexed Views

      【讨论】:

        猜你喜欢
        • 2021-04-17
        • 1970-01-01
        • 2021-08-16
        • 1970-01-01
        • 2016-02-01
        • 2023-03-12
        • 1970-01-01
        • 2011-04-19
        相关资源
        最近更新 更多