首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >SQL MERGE语句中的UPDATE-no-op

SQL MERGE语句中的UPDATE-no-op
EN

Stack Overflow用户
提问于 2011-03-16 03:05:39
回答 1查看 6K关注 0票数 22

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

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

代码语言:javascript
复制
-- 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部分,我宁愿把多余的update去掉,但这样我就得不到OUTPUT子句中的结果行。

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

或者,是否会有一个没有MERGE的更有效的解决方案,例如,通过使用SELECT预计算结果,然后对new=0的行执行INSERT?我很难解释查询计划,因为它基本上归结为“集群索引合并”,与后面跟着INSERT变体的单独SELECT相比,它在性能方面对我来说相当模糊。我想知道SQL Server (带有CU1的2008 R2 )是否真的足够聪明,能够看到UPDATE是无操作的(例如,不需要写入)。

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5316669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档