sql Merge语句中的UPDATE-NO-op?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (8)

我有一个表,里面有一些持久的数据。现在,当我查询它时,我还有一个相当复杂的CTE,它计算结果所需的值,并且需要将缺失的行插入到持久表中。最后,我希望选择由CTE标识的所有行组成的结果,但如果它们已经在表中,则使用表中的数据,并且我需要有关是否刚刚插入了行的信息。

简化后的工作方式如下(如果您愿意尝试,下面的代码作为普通查询运行):

-- Set-up of test data, this would be the persisted table 
DECLARE @target TABLE (id int NOT NULL PRIMARY KEY) ;
INSERT INTO @target (id) SELECT v.id FROM (VALUES (1), (2)) v(id);

-- START OF THE CODE IN QUESTION
-- The result table variable (will be several columns in the end)
DECLARE @result TABLE (id int NOT NULL, new bit NOT NULL) ;

WITH Source AS (
    -- Imagine a fairly expensive, recursive CTE here
    SELECT * FROM (VALUES (1), (3)) AS Source (id)
)
MERGE INTO @target AS Target
    USING Source
    ON Target.id = Source.id
    -- Perform a no-op on the match to get the output record
    WHEN MATCHED THEN 
        UPDATE SET Target.id=Target.id
    WHEN NOT MATCHED BY TARGET THEN
        INSERT (id) VALUES (SOURCE.id)
    -- select the data to be returned - will be more columns
    OUTPUT source.id, CASE WHEN $action='INSERT' THEN CONVERT(bit, 1) ELSE CONVERT(bit, 0) END
      INTO @result ;

-- Select the result
SELECT * FROM @result;

我不喜欢WHEN MATCHED THEN UPDATE部分,我宁愿将多余的更新放在一边,但这样我就不会将结果行放在OUTPUT

这是完成这种数据并返回数据的最有效的方法吗?

提问于
用户回答回答于

您可以声明一个虚拟变量,并在WHERMatch子句中设置它的值。

 DECLARE @dummy int;
 ...
 MERGE
 ...
 WHEN MATCHED THEN
   UPDATE SET @dummy = 0
 ...

扫码关注云+社区