我正在将数据从 SQL Server 2017 迁移到 Postgres 10.5 。
为了比较数据的一致性,我想对表中的行进行哈希处理。
这是我的处理方法。
我将在SQL Server表和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()
函数,而不仅仅是如上所述返回哈希的一个列?
答案 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