【问题标题】:Avoiding multiple rows in call to 'HashBytes' with 'FOR XML RAW'使用“FOR XML RAW”避免在调用“HashBytes”时出现多行
【发布时间】:2015-01-09 14:09:26
【问题描述】:

在通用 ETL 流程中,我将数据从源(表、文件、Web 服务等)选择到数据集市中。

我正在使用 MS-SQL 哈希字节函数来识别行是否已更改。

例如在具有 CountryCode、Zip 和 CityName 的城市表上,主键 = CountryCode 和 Zip

 SELECT CountryCode, Zip,  CityName, 
 CONVERT(VARCHAR(40), HASHBYTES('MD5', 
 (SELECT CityName FROM spo.City sub 
  WHERE sub.Zip = main.Zip  
    AND  sub.CountryCode = main.CountryCode  
    FOR XML RAW )), 2) AS SysCheckSumSCD1 
FROM spo.City main 

我的问题是源中的主键重复

然后在 HASHBYTES 中使用的子选择将包括两列并且两行将具有相同的哈希键。因此我的数据集市将无法正确更新。 此外,我不会被告知源中有重复项。

示例结果:

Zip     CountryCode     CityName        SysCheckSumSCD1
14600   FR              Honfleur        6D8EF511B35621FC0F5CC67AA6B98EEA
14600   FR              Equemauville    6D8EF511B35621FC0F5CC67AA6B98EEA

相反,我希望调用失败。

之前我使用了 CHECKSUM 函数,该函数将实际行作为输入,但在上面的示例中失败了。 但我不得不更改为 HASHBYTES,不幸的是它只接受一个字符串作为输入。这是“FOR XML RAW”部分的原因

如果有任何有用的意见,我将不胜感激。 最好只通过更改上述 SQL 语句来实现的东西,因为它是大型通用解决方案的一部分。而且我的手有点束缚。

我一直在考虑添加一个虚拟聚合函数来强制错误。但是一直不知道怎么做。

【问题讨论】:

    标签: sql-server etl hashbytes


    【解决方案1】:

    周末后回到键盘上,大脑充满活力。我意识到解决方案其实很简单。

    只需通过在其周围添加“SELECT () AS FOO”来使传递给 HASHBYTES 的语句成为子查询。 :-|

    因此语句将如下所示。

    SELECT CountryCode, Zip,  CityName, 
    CONVERT(VARCHAR(40), HASHBYTES('MD5', 
         (SELECT 
          (SELECT CityName 
          FROM spo.City sub 
          WHERE sub.Zip = main.Zip 
          AND  sub.CountryCode = main.CountryCode) AS FOO 
         FOR XML RAW )), 2) AS SysCheckSumSCD1 
    FROM spo.City main
    

    【讨论】:

      猜你喜欢
      • 2017-03-10
      • 2018-10-31
      • 1970-01-01
      • 2013-03-16
      • 2019-01-03
      • 1970-01-01
      • 2012-09-05
      • 2021-07-03
      • 1970-01-01
      相关资源
      最近更新 更多