SQL方法获取整行的MD5或SHA1

Pie*_*e D 10 sql hash md5

是否有"半便携式"方式来获取整行的md5()或sha1()?(或者更好的是,所有字段排序的整行行,即order by 1,2,3,...,n)?不幸的是,不是所有的数据库都是PostgreSQL ......我必须至少处理微软的SQL服务器,Sybase和Oracle.

理想情况下,我想要一个聚合器(服务器端)并使用它来检测行组的变化.例如,在具有某个时间戳列的表中,我想为每个月存储一个唯一的签名.然后我可以快速检测自上次访问以来已经发生变化的月份(我将某些表镜像到运行Greenplum的服务器上)并重新加载它们.

我看了几个选项,例如checksum(*)在tsql中(恐怖:它很容易发生冲突,因为它基于一堆XOR和32位值)hashbytes('MD5', field),但是后者不能应用于整行.这将为我提供一个解决方案,仅针对我必须处理的SQL风格之一.

任何的想法?即使只是上面提到的一个SQL习语,那也很棒.

小智 8

您可以在更新触发器上计算整行的hashbytes值,我将其用作ETL过程的一部分,之前他们正在比较表中的所有列,速度增加很大.

Hashbytes适用于varchar,nvarchar或varbinary数据类型,我想比较整数键和文本字段,将一切都变成一场噩梦,所以我在SQL Server中使用了FOR XML子句,如下所示:

CREATE TRIGGER get_hash_value ON staging_table
FOR UPDATE, INSERT AS  
UPDATE staging_table
SET sha1_hash = (SELECT hashbytes('sha1', (SELECT col1, col2, col3 FOR XML RAW)))
GO
Run Code Online (Sandbox Code Playgroud)

或者,如果您计划通过使用带有for xml子句的子查询对所有行执行许多更新,则可以在触发器之外以类似的方式计算值.如果走这条路线,您甚至可以将其更改为SELECT*,但不能在触发器中,因为每次运行它时,您将获得不同的值,因为每次sha1_hash列都不同.

您可以修改select语句以获得多于1行


Sam*_*Sam 5

在MSSQL中-您可以使用xml在整个行中使用HashBytes。

SELECT MBT.id,
   hashbytes('MD5',
               (SELECT MBT.*
                FROM (
                      VALUES(NULL))foo(bar)
                FOR xml auto)) AS [Hash]
FROM <Table> AS MBT;
Run Code Online (Sandbox Code Playgroud)

您需要该from (values(null))foo(bar)子句来使用xml auto,它没有其他用途。