Получить значения хеш-функции из SQL Server и Oracle и сравнить их? - PullRequest
5 голосов
/ 11 января 2012

Можно ли сгенерировать хеш-код с обоих серверов баз данных и сравнить их?Как написать следующий псевдо SQL в SQL Server?Особенно две getHash функции, которые принимают несколько числовых / плавающих столбцов в SQL-сервере и Oracle.

select s.PK
from sqltable s
    join openquery(oracleLinkedServer, 
      'select PK, getHash(Column1, floatColumn2, ..., floatColumnN) oracleHash 
       from oracleTable') o on o.PK = s.PK
where
    getHash(Column1, floatColumn2, ..., floatColumnN) <> oracleHash

Ответы [ 4 ]

10 голосов
/ 12 января 2012

В SQL Server:

select upper(substring(sys.fn_sqlvarbasetostr(hashbytes('MD5','A')),3,32));

результат:

7FC56270E7A70FA81A5935B72EACBE29

В Oracle:

select rawtohex(
    DBMS_CRYPTO.Hash (
        UTL_I18N.STRING_TO_RAW ('A', 'AL32UTF8'),
        2)
    ) from dual;

результат:

7FC56270E7A70FA81A5935B72EACBE29

Убедитесь, что ваши строки точно такие же (с учетом регистра).Здесь я использовал 'A' в качестве простого примера, но на самом деле это могла быть любая строка.

Если вы избежите различий в типах данных, преобразовав их в большую строку, вы сможете создавать один и тот же хэш md5 для разныхплатформ.Обратите внимание, что SQL Server добавлял к хешу '0x', чтобы обозначить шестнадцатеричное представление, которое я удалил с помощью подстроки.

3 голосов
/ 11 января 2012

В SQL Server у вас есть hashbytes () ; в Oracle у вас есть DBMS_CRYPTO.Hash () . Вы должны быть в состоянии использовать их для вычисления хеша MD5 с обеих сторон, хотя я не уверен, что хеш будет соответствовать ... его стоит попробовать.

Существуют и другие способы сравнения таблиц, но для ответа на ваш вопрос это две встроенные функции на любой платформе.

0 голосов
/ 13 ноября 2018

Если у вас ограниченный доступ к системе 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.

0 голосов
/ 11 января 2012

Вы можете использовать CHECKSUM() в SQL Server для вычисления хеша из нескольких столбцов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...