MERGE语句未更新

时间:2013-08-29 14:37:51

标签: sql sql-server tsql merge

在SQL Server上执行以下操作时,我希望使用值88888888更新NULL,但它会插入一个新行。 有人可以告诉我我做错了吗?

USE tempdb;

CREATE TABLE TableA (ColA CHAR(8), ColB CHAR(8))
CREATE TABLE TableB (ColA CHAR(8), ColB CHAR(8))

INSERT INTO TableA VALUES  ( 'XXXXXXXX', NULL )
INSERT INTO TableA VALUES  ( 'XXXXXXXX', '88888888')

MERGE INTO TableB AS T
USING TableA AS S
ON T.ColA = S.ColA and T.ColB = S.ColB
WHEN MATCHED 
    THEN
      UPDATE
         SET T.ColA = S.ColA, T.ColB = S.ColB
WHEN NOT MATCHED BY TARGET 
    THEN
      INSERT (ColA, ColB) VALUES (S.ColA, S.ColB);

SELECT  * FROM    TableA
SELECT  * FROM    TableB

DROP TABLE TableA
DROP TABLE TableB

非常感谢! 最好的祝福, 史蒂夫

2 个答案:

答案 0 :(得分:5)

a)表本质上是无序的。即使(正如您所期望的那样)合并一次进行一行(参见下面的c),也没有理由在具有null的行之前看不到具有非空列的行的行{ {1}}

b)您的ColB子句指定了ONColA的匹配项。这两行中至少有一行是不同的,所以我希望这两行都不匹配ColB中的行,并且

c)应用SQL语句,就好像所有行同时受到并行影响一样。它不处理一行,然后移动到下一行。所以永远不会有TableB中只有一行。

不幸的是,您发布的内容显然是一个“玩具”示例,因此我无法提供任何有关如何修复它的建议 - 您没有告诉我们真实情况是什么,真实数据是什么样的,为什么你使用TableB等等。

答案 1 :(得分:2)

MERGE INTO TableB AS T
USING TableA AS S
ON T.ColA = S.ColA 
WHEN MATCHED 
THEN
  UPDATE
     SET  T.ColB = S.ColB

请从加入中删除此内容:和T.ColB = S.ColB

此外,您还可以从更新中删除 T.ColA = S.ColA ,因为这些列已经具有相同的值。