首页 文章

SQL Server违反PRIMARY KEY约束

提问于
浏览 1186
0

我在同一台服务器上的不同数据库上有两个表,每个表都有相同的列 .

表A它存在,但我没有创建表和列:

  • test1 varchar(10)not null

  • test2 varchar(5)not null

  • test3 varchar(5)不为空

表B:

CREATE TABLE B
(
     test1 as test2 + test3 PERSISTED NOT NULL,
     test2 varchar NOT NULL,
     test3 varchar NOT NULL

     PRIMARY KEY(test1)
);

我编写更新或插入合并行的查询:

MERGE B AS TARGET
USING A AS SOURCE 
ON (TARGET.test1 = SOURCE.test1) 

WHEN MATCHED AND (TARGET.test2 <> SOURCE.test2 OR TARGET.test3 <> SOURCE.test3 
   THEN
      UPDATE SET TARGET.test2 = SOURCE.test2,
                 TARGET.test3 = SOURCE.test3 

WHEN NOT MATCHED BY TARGET THEN 
    INSERT (test2, test3) 
    VALUES (SOURCE.test2, SOURCE.test3);
GO

我第一次运行查询时,它运行正常,但第二次,我得到一个错误:

违反PRIMARY KEY约束'PK__getSuppl__FCACF30EF3C2476C' . 无法在对象'表B'中插入重复键 . 重复键值为(test2 test3) .

为什么?

我的目标是比较表A中的每一行,如果行存在于B中,而其中一行没有test1,则更新else表中的插入到B.

谢谢

2 回答

  • 2

    原因:表A中有一些数据表示test1 <> test2 test3 . 这样的数据会导致提到的错误;更重要的是,这种“错误的”数据也可能在表B中产生“逻辑错误”的数据;

    例如:

    CREATE TABLE A
    (
         test1 varchar(10) NOT NULL,
         test2 varchar(10) NOT NULL,
         test3 varchar(10) NOT NULL
         PRIMARY KEY(test1)
    );
    CREATE TABLE B
    (
         test1 as test2 + test3 PERSISTED NOT NULL,
         test2 varchar(10) NOT NULL,
         test3 varchar(10) NOT NULL
         PRIMARY KEY(test1)
    );
    insert into A values ('AB', 'A', 'C');
    insert into B values ('A', 'B');
    insert into A values ('ABB', 'A', 'BC');
    

    问题1:行('ABB','A','BC')将导致SQL错误;

    问题2:表A中的行('AB','A','C')将覆盖表B中的现有行('A','B');

    解决方案:您可能希望从源(表A)中消除“错误”数据,例如:

    MERGE B AS TARGET
    USING A AS SOURCE 
    ON (TARGET.test1 = SOURCE.test1 AND SOURCE.test1 = SOURCE.test2 + SOURCE.test3 ) 
    
    WHEN MATCHED AND (TARGET.test2 <> SOURCE.test2 OR TARGET.test3 <> SOURCE.test3) 
       THEN
          UPDATE SET TARGET.test2 = SOURCE.test2,
                     TARGET.test3 = SOURCE.test3 
    
    WHEN NOT MATCHED BY TARGET AND (SOURCE.test1 = SOURCE.test2 + SOURCE.test3) THEN 
        INSERT (test2, test3) 
        VALUES (SOURCE.test2, SOURCE.test3);
    GO
    

    希望能帮助到你 .

  • 0

    首先,在SQL Server中,不应该使用没有长度的 varchar (和相关类型) . 你是否意识到 varchar - 在这种情况下 - 只允许一个角色?如果这是你想要的,请明确并使用 varchar(1) .

    如果表A中的数据如下所示,您将获得该行为:

    test1   test2    test3
      C       A        B
    

    第一次通过 merge 时, test1 将不匹配(假设第二个表中没有 C ) . 第一次,代码添加行:

    AB       A        B
    

    它仍然与 C 不匹配,因此您将尝试再次添加它 . 但是,这将违反您的主键约束 . 因此,插入失败 .

    您有数据问题 .

相关问题