2012-08-08 51 views
12

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%。

非常感謝

回答

10

可以使用CHECKSUM_AGG骨料。它是爲此目的而製作的。

+4

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

1

對於單行哈希:

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

1

另一種方法:

-- 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; 
9
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