我在同一台服务器上的不同数据库上有两个表,每个表都有相同的列 .
表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 回答
原因:表A中有一些数据表示test1 <> test2 test3 . 这样的数据会导致提到的错误;更重要的是,这种“错误的”数据也可能在表B中产生“逻辑错误”的数据;
例如:
问题1:行('ABB','A','BC')将导致SQL错误;
问题2:表A中的行('AB','A','C')将覆盖表B中的现有行('A','B');
解决方案:您可能希望从源(表A)中消除“错误”数据,例如:
希望能帮助到你 .
首先,在SQL Server中,不应该使用没有长度的
varchar
(和相关类型) . 你是否意识到varchar
- 在这种情况下 - 只允许一个角色?如果这是你想要的,请明确并使用varchar(1)
.如果表A中的数据如下所示,您将获得该行为:
第一次通过
merge
时,test1
将不匹配(假设第二个表中没有C
) . 第一次,代码添加行:它仍然与
C
不匹配,因此您将尝试再次添加它 . 但是,这将违反您的主键约束 . 因此,插入失败 .您有数据问题 .