2014-10-06 121 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

相关问题