我在同一台服务器上的不同数据库中有两个表,每个表都有相同的列。
表A它存在,但我没有创建表格和列:
表B:
CREATE TABLE B
(
test1 as test2 + test3 PERSISTED NOT NULL,
test2 varchar NOT NULL,
test3 varchar NOT NULL
PRIMARY KEY(test1)
);
我编写了更新或插入带有merge的行的查询:
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约束&#39; PK__getSuppl__FCACF30EF3C2476C&#39;。无法在对象&#39;表B&#39;中插入重复键。重复键值为(test2 + test3)。
为什么?
我的目标是比较表A中的每一行,如果该行存在于B中,而其中一列没有test1则不同,则更新从表A到B的其他插入。
由于
答案 0 :(得分:2)
首先,在SQL Server中,不应使用varchar
(和相关类型)而不使用长度。你是否意识到varchar
- 在这种情况下 - 只允许一个角色?如果这是您想要的,请明确并使用varchar(1)
。
如果表A中的数据如下所示,您将获得该行为:
test1 test2 test3
C A B
第一次通过merge
时,test1
将不匹配(假设第二个表中没有C
)。第一次,代码添加了行:
AB A B
它仍然与C
不匹配,因此您将尝试再次添加它。但是,这将违反您的主键约束。因此,插入失败。
您遇到了数据问题。
答案 1 :(得分:0)
原因: 表A中有一些数据表示test1&lt;&gt;测试2 + TEST3。这样的数据会导致提到的错误; 更重要的是,这样的&#34;错误&#34;数据也可能产生逻辑错误&#34;表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:行(&#39; ABB&#39;,&#39; A&#39;,&#39; BC&#39;)将导致SQL错误;
问题2:表A中的行(&#39; AB&#39;,&#39; A&#39;,&#39; C&#39;)将覆盖现有行(&#39; A&#39;表B中的,&#39; B&#39;;
解决方案: 你可能想要消除错误的&#34;来自源(表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
希望它有所帮助。