Избегание нескольких строк при вызове "HashBytes" с помощью "FOR XML RAW"
В общем потоке ETL я выбираю данные из источника (таблица, файл, веб-сервис и т. Д.) В datamart.
Я использую хэш-функцию 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, будет включать оба столбца, и обе строки будут иметь один и тот же хэш-ключ. Следовательно, мой datamart не будет корректно обновлен. Кроме того, мне не сообщат, что в источнике есть дубликаты.
Пример результата:
Zip CountryCode CityName SysCheckSumSCD1
14600 FR Honfleur 6D8EF511B35621FC0F5CC67AA6B98EEA
14600 FR Equemauville 6D8EF511B35621FC0F5CC67AA6B98EEA
Вместо этого я хотел бы, чтобы звонок не состоялся.
Ранее я использовал функцию CHECKSUM, которая взяла фактическую строку в качестве входных данных и потерпела неудачу в приведенном выше примере. Но мне пришлось перейти на HASHBYTES, который, к сожалению, принимает в качестве входных данных только строку. Что является причиной для 'FOR XML RAW'
Буду признателен за любой полезный вклад. Желательно что-то, что можно реализовать, просто изменив приведенный выше SQL-оператор, поскольку он является частью большого универсального решения. И мои руки немного связаны.
Я думал о добавлении фиктивной агрегатной функции, чтобы вызвать ошибку. Но не смог понять, как это сделать.
1 ответ
После возвращения на клавиатуру после выходных с перезаряженным мозгом. Я понимаю, что решение на самом деле довольно простое.
Просто сделайте оператор, переданный 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