在sql server中为一组行创建一个散列

问题描述:

SQL Server 2012中是否有任何方法来生成一组行和列的散列?在sql server中为一组行创建一个散列

我想生成一个散列,将其存储在父记录上。更新进来时,我会将传入的散列与父记录散列进行比较,然后我会知道数据是否已更改。

因此,像这样就好了:

SELECT GENERATEHASH(CONCATENATE(Name, Description, AnotherColumn)) 
FROM MyChildTable WHERE ParentId = 2 -- subset of data belong to parent record 2 

“CONCATENATE”将是一个聚合函数,这不仅CONCAT列,而且,在结果集内的行。像MAX一样,但将所有内容都返回为字符串连接。

希望这可以帮助你明白我的意思!

我试图解决的根本问题是我的客户端系统执行大量分层数据的导入。如果我可以通过使用散列来避免处理,那么我认为这将节省大量时间。目前,SP在处理重复数据时运行速度降低了300%。

非常感谢

可以使用CHECKSUM_AGG骨料。它是为此目的而制作的。

+4

不幸的是,CHECKSUM已知其弱点(即实际碰撞)。例如。十进制类型http://sqlserverpains.blogspot.com.au/2008/06/checksum-pains.html所以只是要小心。 – Shiv 2015-03-31 05:45:20

对于单行哈希:

select HASHBYTES('md5', Name + Description + AnotherColumn) 
FROM MyChildTable WHERE ParentId = 2 

为表校验:

select sum(checksum(Name + Description + AnotherColumn)*1.0) 
FROM MyChildTable WHERE ParentId = 2 
+0

这是否从整个结果集产生一个哈希?或者它会产生多个散列,MyChildTable中的每一行都有一个散列? – krisdyson 2012-08-08 10:57:50

+0

尝试在我的编辑中的第二个解决方案。 – 2012-08-08 11:04:14

+0

我再次更新,以防止整数溢出。 – 2012-08-08 11:08:28

另一种方法:

-- compute a single hash value for all rows of a table 
begin 

    set nocount on; 

    -- init hash variable 
    declare @tblhash varchar(40); 
    set @tblhash = 'start'; 

    -- compute a single hash value 
    select @tblhash = sys.fn_varbintohexsubstring(0, hashbytes('sha1',(convert(varbinary(max),@tblhash+ 
    (select sys.fn_varbintohexsubstring(0,hashbytes('sha1',(convert(varbinary(max), 
    -- replace 'select *' if you want only specific columns to be included in the hash calculation 
    -- [target table] is the name of the table to calc the hash from 
    -- [row_id] is the primary key column within the target table 
    -- modify those in the next lines to suit your needs: 
    (select * from [target_table] obj2 where obj2.[row_id]=obj1.[row_id] for xml raw) 
    ))),1,0)) 
    ))),1,0) 
    from [target_table] obj1; 

    set nocount off; 

    -- return result 
    select @tblhash as hashvalue; 

end; 

select HashBytes('md5',convert(varbinary(max),(SELECT * FROM MyChildTable WHERE ParentId = 2 FOR XML AUTO))) 

但HASHBYTES仅限于8000个字节......你可以做一个函数来获得德MD5具有每8000个字节....

+0

如果您使用SQL Server 2016或更高版本,它具有一些JSON支持,我建议使用'FOR JSON AUTO'而不是'FOR XML AUTO',因为在我进行的一些测试中,这似乎快了约2倍。 – Isak 2017-08-01 15:28:58