2014-10-06 168 views
4

我真的不知道CHECKSUM_AGG()是如何工作的,儘管我知道它是通過使用XOR構建的。這就解釋了爲什麼當你傳遞相等的整數時它返回0爲什麼CHECKSUM_AGG()爲完全不同的輸入值返回相同的值?

但是,爲什麼我會在以下SQL中獲得相同的彙總校驗和,其中輸入值是唯一的?

DECLARE @test1 TABLE (chksum INT) 
INSERT INTO @test1 VALUES (2147473855), (2147473343) 
SELECT CHECKSUM_AGG(chksum) 
FROM @test1 

DECLARE @test2 TABLE (chksum INT) 
INSERT INTO @test2 VALUES (2147474831), (2147472271) 
SELECT CHECKSUM_AGG(chksum) 
FROM @test2 

解釋將不勝感激。謝謝!

回答

3

存在已知的問題與SQL Server校驗和與CHECKSUM_AGG實現:CHECKSUM weakness explained

使用HASHBYTES代替:Using HASHBYTES to compare columns

Microsoft: 如果表達式列表中的變化的一個值,該列表的校驗也普遍發生變化。但是,校驗和不會發生變化的可能性很小。出於這個原因,我們不建議使用CHECKSUM來檢測值是否已更改,除非您的應用程序能夠容忍偶爾錯過更改。 考慮使用HashBytes而不是。當指定MD5散列算法時,HashBytes返回兩個不同輸入的相同結果的概率遠遠低於CHECKSUM的結果。

您不能直接在行之間使用HASHBYTES - 有一種解決方法here

以下是更小的數字比較,使用HASBYTES解決方法:

DECLARE @test1 TABLE (chksum INT) 
DECLARE @test2 TABLE (chksum INT) 

INSERT INTO @test1 VALUES (50), (3), (26) 
INSERT INTO @test2 VALUES (45), (0), (6) 

SELECT [Values] = '50, 3, 26', 
     [Checksum] = CHECKSUM_AGG(chksum), 
     -- HashBytes is limited to 8000 bytes only 
     [Hashbytes] = HashBytes('md5',convert(varbinary(max),(SELECT * FROM @test1 FOR XML AUTO))) 
FROM @test1 

UNION ALL 
SELECT [Values] = '45, 0, 6',  
     [Checksum] = CHECKSUM_AGG(chksum), 
     -- HashBytes is limited to 8000 bytes only 
     [Hashbytes] = HashBytes('md5',convert(varbinary(max),(SELECT * FROM @test2 FOR XML AUTO))) 
FROM @test2 

CHECKSUM_AGG vs HASHBYTES

相關問題