SQL Servrer中等效的Postgres MD5()是什么?

时间:2019-11-06 10:21:33

标签: sql-server postgresql md5 database-migration

我正在将数据从 SQL Server 2017 迁移到 Postgres 10.5

为了比较数据的一致性,我想对表中的行进行哈希处理。

这是我的处理方法。

我将在SQL Server表和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哈希处理。

我在 SQL Server 2017 https://docs.microsoft.com/en-us/sql/t-sql/functions/hashbytes-transact-sql?view=sql-server-ver15

中查看了HASHBYTES()

但是它仅对一列进行哈希处理。在varchar()的列中也是如此。

如何对表中的所有行和所有列执行HASHBYTES()函数,而不仅仅是如上所述返回哈希的一个列?

1 个答案:

答案 0 :(得分:1)

MSSQL中的HASHBYTES('MD5',x)等同于Postgres中的MD5(x)。这两个函数仅接受一个值作为输入。

您真正要问的是如何复制:: 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