为什么CHECKSUM_AGG()对于完全不同的输入值返回相同的值?

5 t-sql

CHECKSUM_AGG()尽管我了解它是通过使用XOR某种方式构建的,但我并没有真正了解它是如何工作的。这就解释了为什么0当您只传递相等的整数时返回它。

但是,为什么在下面的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
Run Code Online (Sandbox Code Playgroud)

一个解释将不胜感激。谢谢!

Ily*_*sky 5

SQL Server CHECKSUM 和 CHECKSUM_AGG 实现存在已知问题:CHECKSUM 弱点解释

使用 HASHBYTES 代替:使用 HASHBYTES 比较列

来自Microsoft:如果表达式列表中的值之一发生更改,则列表的校验和通常也会更改。然而,校验和有极小可能不会改变。因此,我们不建议使用 CHECKSUM 来检测值是否已更改,除非您的应用程序可以容忍偶尔丢失更改。考虑使用 HashBytes 代替。当指定 MD5 哈希算法时,HashBytes 对于两个不同的输入返回相同结果的概率远低于 CHECKSUM。

您不能直接跨行使用 HASHBYTES -这里有一种解决方法。

以下是使用 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
Run Code Online (Sandbox Code Playgroud)

CHECKSUM_AGG 与 HASHBYTES