使用'FOR XML RAW'避免调用'HashBytes'中的多行

时间:2015-01-09 14:09:27

标签: sql-server etl hashbytes

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

我使用MS-SQL hashbyte-function来识别行是否已更改。

E.g。在具有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中使用的子选择将包括两列,并且两行将具有相同的hashkey。因此我的datamart将无法正确更新。 此外,我没有被告知源头有重复信息。

示例结果:

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

相反,我希望呼叫失败。

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

我很感激任何有用的输入。 通过更改上述SQL语句可以实现的优先级,因为它是大型通用解决方案的一部分。我的手有点束缚。

我一直在考虑添加虚拟聚合函数来强制错误。但是,天堂已经能够弄清楚如何去做。

1 个答案:

答案 0 :(得分:0)

周末用充电的大脑回到键盘后。我意识到解决方案实际上非常简单。

通过添加' 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