【问题标题】:Do not Update the Values in Merge statement if old values do not change while update in Merge如果旧值在 Merge 中更新时未更改,则不要在 Merge 语句中更新值
【发布时间】:2021-04-29 23:51:41
【问题描述】:
MERGE PFM_EventPerformance_MetaData AS TARGET
USING
(
    SELECT
         [InheritanceMeterID] = @InheritanceMeterPointID
        ,[SubHourlyScenarioResourceID] = @SubHourlyScenarioResourceID
        ,[MeterID] = @MeterID--internal ID
        ,[BaselineID] = @BaselineID--internal ID                            
        ,[UpdateUtc] = GETUTCDATE()
) 
AS SOURCE ON
    TARGET.[SubHourlyScenarioResourceID] = SOURCE.[SubHourlyScenarioResourceID]
    AND TARGET.[MeterID] = SOURCE.[MeterID]--internal ID
    AND TARGET.[BaselineID] = SOURCE.[BaselineID]--internal ID
WHEN MATCHED  THEN UPDATE SET
     @MetaDataID = TARGET.ID--get preexisting ID when exists (must populate one row at a time)              
   ,InheritanceMeterID = SOURCE.InheritanceMeterID                      
    ,[UpdateUtc] = SOURCE.[UpdateUtc]
WHEN NOT MATCHED
    THEN INSERT
    (
         [InheritanceMeterID]
        ,[SubHourlyScenarioResourceID]
        ,[MeterID]--internal ID
        ,[BaselineID]--internal ID                          
    )
    VALUES
    (
         SOURCE.[InheritanceMeterID]
        ,SOURCE.[SubHourlyScenarioResourceID]
        ,SOURCE.[MeterID]--internal ID
        ,SOURCE.[BaselineID]--internal ID                           
    );

在上述查询中,如果旧值没有变化,我不想更新目标表中的值。我不确定如何实现这一点,因为我很少使用 Merge 语句。请帮我解决问题。提前致谢

【问题讨论】:

  • 你不能只给WHEN MATCHED AND someconditionhere THEN UPDATE添加一个条件吗?
  • 你能给我一些示例代码吗@Charlieface
  • 我刚做了。但我不确定你想要什么,不清楚。如果您愿意,WHEN MATCHED 可以有一个额外的条件。我们可以这样做,例如:WHEN MATCHED AND target.InheritanceMeterID <> source.InheritanceMeterID AND target.UpdateUtc <> source.UpdateUtc THEN UPDATE SET...
  • 谢谢这是我需要的@Charlieface

标签: sql sql-server tsql sql-merge


【解决方案1】:

最好分两个阶段完成。

第 1 阶段:根据条件合并更新

SO Answer from before(感谢@Laurence!)

第 2 阶段:要比较的哈希键条件

限制:最多 4000 个字符,包括列分隔符

在一个条件下比较多个列的一种相当简单的方法是在两侧使用 HASHBYTES( , ) 生成的计算列。

这将编写大量代码从合并语句转移到表生成。

快速示例:

CREATE TABLE dbo.Test
(
  id_column  int   NOT NULL,
  dsc_name1  varchar(100),
  dsc_name2  varchar(100),
  num_age    tinyint,
  flg_hash   AS HashBytes( 'SHA1', 
      Cast( dsc_name1 AS nvarchar(4000) ) 
      + N'•' + dsc_name2 + N'•' + Cast( num_age AS nvarchar(3) )
      ) PERSISTED
)
;

比较源和目标之间的列 flg_hash 可以快速进行比较,因为它只是两个 20 位 varbinary 列之间的比较。

HashBytes 合作的几个告诫:

  • 该函数仅适用于总共 4000 个 nvarchar 字符
  • 短比较代码的权衡在于在视图和表格中生成正确的顺序
  • 2^50+ for SHA1 附近存在重复冲突的可能性 - 作为安全机制,这现在被认为是不安全的,几年前 MS 试图放弃 SHA1 作为算法
  • 如果哈希字节代码不在考虑修改范围内,则可以忽略比较表和视图中添加的列
  • 总的来说,我发现在比较多个列时,这可能会使我的服务器引擎过载,但哈希键比较从来没有出现过问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-26
    • 2021-01-06
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 2022-12-03
    相关资源
    最近更新 更多