加入收藏 | 设为首页 | 会员中心 | 我要投稿 财气旺网 - 财气网 (https://www.caiqiwang.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > MsSql教程 > 正文

sql-server – MERGE目标表的一个子集

发布时间:2021-01-12 08:57:22 所属栏目:MsSql教程 来源:网络整理
导读:我试图使用MERGE语句插入或删除表中的行,但我只想对这些行的子集进行操作. MERGE的文档有一个措辞非常强烈的警告: It is important to specify only the columns from the target table that are used for matching purposes. That is,specify columns from

使用公用表表达式会为ON子句添加谓词带来类似的风险,但原因略有不同.在许多情况下,这将是安全的,但它需要专家分析执行计划以确认这一点(以及广泛的实际测试).例如:

WITH TARGET AS 
(
    SELECT * 
    FROM @CategoryItem
    WHERE CategoryId = 2
)
MERGE INTO TARGET
USING 
(
    SELECT CategoryId,ItemId
    FROM @DataSource
    WHERE CategoryId = 2
) AS SOURCE ON
    SOURCE.ItemId = TARGET.ItemId
    AND SOURCE.CategoryId = TARGET.CategoryId
WHEN NOT MATCHED BY TARGET THEN
    INSERT (CategoryId,DELETED.ItemId) AS ItemId
;

通过更优化的计划,可以产生正确的结果(不重复):

该计划仅从目标表中读取类别2的行.如果目标表很大,这可能是一个重要的性能考虑因素,但使用MERGE语法很容易出错.

有时,将MERGE编写为单独的DML操作更容易.这种方法甚至可以比单一的MERGE表现更好,这一事实常常让人惊讶.

DELETE ci
FROM @CategoryItem AS ci
WHERE ci.CategoryId = 2
AND NOT EXISTS 
(
    SELECT 1 
    FROM @DataSource AS ds 
    WHERE 
        ds.ItemId = ci.ItemId
        AND ds.CategoryId = ci.CategoryId
);

INSERT @CategoryItem
SELECT 
    ds.CategoryId,ds.ItemId
FROM @DataSource AS ds
WHERE
    ds.CategoryId = 2;

(编辑:财气旺网 - 财气网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读