Если у вас ограниченный доступ к системе Oracle и вам не предоставлены разрешения на выполнение на DBMS_CRYPTO.Hash()
, вы все равно можете использовать DBMS_OBFUSCATION_TOOLKIT.MD5()
для создания одинакового хэшированного значения как на Oracle, так и на SQL Server.Вам просто нужно преобразовать строку в ту же кодовую страницу, что и на компьютере с SQL Server.Я полагаю, что по умолчанию в большинстве североамериканских окон Windows windows-1252 ANSI Latin 1; Western European (Windows)
(из https://docs.microsoft.com/en-us/windows/desktop/intl/code-page-identifiers)
) мне не особенно нравятся вызовы функций в моих предложениях WHERE
, поэтому я помещаю хэш стороны SQL вCTE, а затем присоединиться к результатам OPENQUERY
.
;WITH sqlHash AS
(
SELECT s.PK
,UPPER(CONVERT(CHAR(32), HASHBYTES('MD5', s.Column1 + '|' + s.Column2 + '|' + s.ColumnN), 2)) AS sqlHash
FROM sqltable s
)
SELECT s.PK
FROM sqlHash s
JOIN OPENQUERY
( oracleLinkedServer, '
SELECT
PK
,CONVERT(UPPER(RAWTOHEX(
SYS.DBMS_OBFUSCATION_TOOLKIT.MD5(input_string => "oraColumn1" || ''|'' || "oraColumn2" || ''|'' || "oraColumnN")
)),''AL32UTF8'',''WE8MSWIN1252'') AS oracleHash
FROM oracleTable' ) o ON o.PK = s.PK
WHERE s.sqlHash <> o.oracleHash
Несколько моментов, на которые здесь можно обратить внимание, которые могут быть неочевидными.
Сначала я добавляю каналсимвол |
между каждым столбцом в объединенном тексте. Это позволяет дифференцировать комбинации, такие как "digital" + "aaron"
и "digi" + "talaaron"
, от создания одного и того же хэша, поскольку строка станет "digital|aaron"
и "digi|talaaron"
, которые должны давать различные хэшированные значения.
Во-вторых, когда мы получаем, что сторона SQL имеет в CTE, значение возвращается как VARBINARY
. Если бы мы только отобразили это значение, было бы ведущее 0x
. Но мы хотимудалите это, а также преобразуйте значение во что-то более полезное, чем VARBINARY
. Поэтому мы конвертируем в CHAR(32)
со стилем 2
.