使用 'FOR XML RAW' 避免在调用 'HashBytes' 时出现多行
Avoiding multiple rows in call to 'HashBytes' with 'FOR XML RAW'
在通用 ETL 流程中,我从源(表、文件、网络服务等)中选择数据并将其放入数据集市。
我正在使用 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 语句即可实现,因为它是大型通用解决方案的一部分。而且我的手有点被束缚了。
我一直在考虑添加一个虚拟聚合函数来强制错误。但是一直没弄明白怎么做。
周末带着充电的大脑回到键盘后。我意识到解决方案其实很简单。
只需在传递给 HASHBYTES 的语句周围添加 'SELECT () AS FOO' 使其成为一个子查询。 :-|
所以声明将如下所示。
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
在通用 ETL 流程中,我从源(表、文件、网络服务等)中选择数据并将其放入数据集市。
我正在使用 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 语句即可实现,因为它是大型通用解决方案的一部分。而且我的手有点被束缚了。
我一直在考虑添加一个虚拟聚合函数来强制错误。但是一直没弄明白怎么做。
周末带着充电的大脑回到键盘后。我意识到解决方案其实很简单。
只需在传递给 HASHBYTES 的语句周围添加 'SELECT () AS FOO' 使其成为一个子查询。 :-|
所以声明将如下所示。
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