Что эквивалентно Postgres MD5 () в SQL-сервере? - PullRequest
1 голос
/ 06 ноября 2019

Я переношу данные из SQL Server 2017 в Postgres 10,5 .

Чтобы сравнить согласованность данных, я хочу выполнить хеширование строк втаблица.

Это мой подход к этому.

Я выдам запрос к таблице сервера SQL и таблице Postgres и получу список хэшей для всех строк. У меня будет два хеш-списка.

  1. Хеш-список таблицы SQL Server
  2. Хеш-список таблицы Postgres

Я могу сравнить их оба и проверить,данные согласованы.

Я нашел функцию для хеширования строк в таблице в Postgres .

select md5(f::text) from table_name as f

Он возвращает хэши для всех строк втаблица, как показано ниже.

hash1_for_row1
hash2_for_row2
hash3_for_row3
hash4_for_row4
....

Но я не смог найти эквивалентную функцию или что-то в SQL Server для того же хеширования MD5.

IПосмотрел HASHBYTES() в SQL Server 2017 https://docs.microsoft.com/en-us/sql/t-sql/functions/hashbytes-transact-sql?view=sql-server-ver15

Но он хэширует только один столбец. Это также относится к столбцу, который имеет varchar().

Как мне выполнить функцию HASHBYTES() для всех строк и всех столбцов таблицы, а не только для одного столбца, который возвращает хэши, как упомянуто выше?

1 Ответ

0 голосов
/ 06 ноября 2019

HASHBYTES ('MD5', x) в MSSQL является эквивалентом MD5 (x) в Postgres. Обе функции принимают только одно значение в качестве входных данных.

На самом деле вы спрашиваете, как реплицировать поведение :: text, которое преобразует всю таблицу в массив текстовых значений. Одна из проблем заключается в том, что вывод преобразования строки в виде текста в Postgres очень специфичен для Postgres. Правила форматирования может быть трудно воспроизвести точно на другой платформе, и любые изменения в цитировании, например, приведут к другому хешу. Лучшим вариантом может быть преобразование ваших данных в более стандартный формат, такой как JSON, и последующее хеширование этого результата. Например:

MS SQL:

WITH p (ky,val) AS
(SELECT 1,'foo' UNION ALL SELECT 2,'bar')
SELECT j, HASHBYTES('MD5',CAST(j AS VARCHAR(MAX))) AS md5
FROM p AS p1
CROSS APPLY (SELECT * FROM p WHERE p.ky=p1.ky FOR JSON AUTO, WITHOUT_ARRAY_WRAPPER) AS t(j);

{"ky":1,"val":"foo"}    84C700DA7093081E7A800D1790BE09CE
{"ky":2,"val":"bar"}    A364B3F954F1A875540FE361CABFFD2A

PostgreSQL:

WITH p (ky,val) AS
(SELECT 1,'foo' UNION ALL SELECT 2,'bar'),
p1 AS
(SELECT row_to_json(p) as j
FROM p)
SELECT j,md5(j::text) as md5 from p1;

{"ky":1,"val":"foo"}    84c700da7093081e7a800d1790be09ce
{"ky":2,"val":"bar"}    a364b3f954f1a875540fe361cabffd2a
...