【问题标题】:Checking for duplicates in 2 columns before insert involving NULL, SQL Server在插入涉及 NULL、SQL Server 之前检查 2 列中的重复项
【发布时间】:2020-10-24 04:47:30
【问题描述】:

目前我有一个带有 PrimaryKey、column1 和 column2 的 table1。 我的目标是,在将数据插入表之前检查 column1 + column2 是否唯一。

示例: 表中的当前数据

**Primary key           column1           column2**
     1                    1               banana
     2                   NULL              NULL
     3                    2                NULL
     4                    1                NULL

应该成功插入以下数据:

**Primary key           column1           column2**
       5                   1               apple
       6                   3               banana
       7                   4                NULL

应该无法插入以下数据:

**Primary key           column1           column2**
       8                   1               banana
       9                   2                NULL

我会让这 2 个文件唯一,但我不能,因为我现在不能用数据填充 NULL 值。enter image description here

【问题讨论】:

    标签: sql sql-server insert duplicates


    【解决方案1】:

    您可以将表格定义为:

    create table t (
      a int primary key not null,
      b int,
      c varchar(10),
      constraint uq1 unique (b, c)
    );
    
    insert into t (a, b, c) values (1, 1, 'banana');
    insert into t (a, b, c) values (2, null, null);
    insert into t (a, b, c) values (3, 2, null);
    insert into t (a, b, c) values (4, 1, null);
    insert into t (a, b, c) values (5, 1, 'apple');
    insert into t (a, b, c) values (6, 3, 'banana');
    insert into t (a, b, c) values (7, 4, null);
    insert into t (a, b, c) values (8, 1, 'banana'); -- fails
    insert into t (a, b, c) values (9, 2, null); -- fails
    

    请参阅SQL<>Fiddle 的运行示例。

    重要提示:您在 SQL Server 中看到的行为偏离了 SQL 标准——我什至会说这是错误的。 SQL Server 将NULL 视为真正的不同值,但它不应该;在 SQL 中null 表示“存在但缺失的值,而不是缺少值”。通过比较所有其他数据库(我知道)将NULL 视为一个非值,一个缺失值,不能与另一个NULL 进行比较。由于这个异常,这个解决方案只适用于SQL Server。

    【讨论】:

    • 谢谢,这似乎是我正在寻找的解决方案。但是,我对 SQL Server 的经验非常少,所以请您解释一下如何将约束添加到我现有的表和我的 2 个字段中?谢谢
    • 编辑:我尝试了下一个:ALTER TABLE t ADD CONSTRAINT b_c UNIQUE (b,c); 但是,我收到下一个错误:Msg 1505, Level 16, State 1, Line 1 CREATE UNIQUE INDEX 语句终止,因为为对象名称“dbo.t”和索引名称“b_c”。重复键值为 (, )。是的,我将有 b = NULL 和 c = NULL 的数据
    • @AnAcount 嗯......这是这个带有空值的 SQL Server 错误的副作用。但是,有一种解决方法。您可以创建“部分唯一索引”,而不是创建“唯一约束”。试试:create unique index ix1 on t (b, c) where b is not null and c is not null.
    【解决方案2】:

    您可以使用EXCEPT 运算符:

    INSERT INTO table1  (column1,column2) 
    SELECT 1, NULL
    
    EXCEPT
    
    SELECT column1,column2
    FROM table1 ;
    

    【讨论】:

      【解决方案3】:

      您可以在该表上创建 UNIQUE CONSTRAINT。

      ALTER TABLE TableName 
      ADD CONSTRAINT UNIQUE (column1, column2);
      

      【讨论】:

      • 这并没有解决问题。 OP 指出他们无法使字段唯一,因为它们可能包含空值,并且正在明确寻找一种方法来识别它们在插入数据之前是唯一的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-28
      • 2021-01-20
      • 1970-01-01
      • 2011-12-04
      • 2023-04-02
      相关资源
      最近更新 更多