password hashbytes sql sql-server tsql sql-server-2008-r2 checksum

hashbytes - md5 sql server



¿Qué condiciones causan que CHECKSUM_AGG devuelva 0? (1)

Esto puede suceder si, por ejemplo, hay un número par de filas, o si los valores se suman a ciertos valores (por ejemplo, 14). Estos dos rinden 0:

SELECT CHECKSUM_AGG(N) FROM (VALUES (1),(2),(3),(4),(4)) AS T(N); SELECT CHECKSUM_AGG(N) FROM (VALUES (2),(3),(4),(5)) AS T(N);

Pero estos no:

SELECT CHECKSUM_AGG(N) FROM (VALUES (1),(2),(3),(4),(5)) AS T(N); SELECT CHECKSUM_AGG(N) FROM (VALUES (2),(3),(4),(6)) AS T(N);

14 puede ser solo una coincidencia (y no ocurre con ese valor en 6 filas), lo menciono solo porque es el único patrón que noté aquí. No sé si alguno de estos casos está documentado.

Además, sabe que CHECKSUM_AGG está documentado oficialmente como no confiable , es decir, puede no reflejar con precisión un cambio de datos, ¿no? El documento no entra en detalles sobre esto, simplemente indica que a veces no le dirá que ha habido un cambio, incluso si lo ha hecho. (La redacción actual es "Sin embargo, hay una pequeña posibilidad de que la suma de comprobación no cambie").

De todos modos, Michael Swart parece haber descubierto que CHECKSUM_AGG es solo XOR (aquí está su prueba):

CREATE TABLE #f(a FLOAT); GO INSERT #f VALUES (RAND()); GO 20 DECLARE @i INT = 0; SELECT @i = @i ^ CHECKSUM(a) FROM #f; SELECT @i, CHECKSUM_AGG(CHECKSUM(a)) FROM #f; GO DROP TABLE #f; GO

Como continúa explicando, esto puede llevar a resultados engañosos cuando el rango de valores es muy pequeño, ya que las probabilidades de generar una suma de comprobación confiable disminuyen rápidamente.

Parece que hay una serie de condiciones que provocan que CHECKSUM_AGG devuelva 0 que no esperaba. Solo he podido encontrar uno discutido, que es que los valores duplicados lo causarán. Eso se puede resolver a través de DISTINCT o GROUP BY .

También encontré un par de escenarios más que tienen menos sentido para mí. Una fue proporcionada por mi jefe y otra por MSDN . Estos no sé cómo explicarlo. Aquí hay algunos SQL que demuestran los escenarios:

SELECT CHECKSUM_AGG(T.Number) AS ChecksumAgggregate FROM ( VALUES (2) , (3) , (4) , (5) )AS T(Number) DECLARE @t TABLE ( Category VARCHAR(15), Value VARCHAR(10) ) INSERT @t ( Category , Value ) VALUES (''OneCharacter'',''a'') ,(''OneCharacter'',''b'') ,(''OneCharacter'',''c'') ,(''OneCharacter'',''d'') ,(''TwoCharacters'',''aa'') ,(''TwoCharacters'',''bb'') ,(''TwoCharacters'',''cc'') ,(''TwoCharacters'',''dd'') ,(''ThreeCharacters'',''aaa'') ,(''ThreeCharacters'',''bbb'') ,(''ThreeCharacters'',''ccc'') ,(''ThreeCharacters'',''ddd'') ,(''SixCharacters'',''aaaaaa'') ,(''SixCharacters'',''bbbbbb'') ,(''SixCharacters'',''cccccc'') ,(''SixCharacters'',''dddddd'') ,(''AllValues'',''a'') ,(''AllValues'',''b'') ,(''AllValues'',''c'') ,(''AllValues'',''d'') ,(''AllValues'',''aa'') ,(''AllValues'',''bb'') ,(''AllValues'',''cc'') ,(''AllValues'',''dd'') ,(''AllValues'',''aaa'') ,(''AllValues'',''bbb'') ,(''AllValues'',''ccc'') ,(''AllValues'',''ddd'') ,(''AllValues'',''aaaaaa'') ,(''AllValues'',''bbbbbb'') ,(''AllValues'',''cccccc'') ,(''AllValues'',''dddddd'') select Category, CHECKSUM_AGG(CHECKSUM(Value)) from @t group by Category select Category, Value, CHECKSUM(Value) ValueChecksum from @t

No son más que 0 en estos ejemplos de CHECKSUM_AGG de estas consultas. La última consulta muestra que ninguno de los valores de CHECKSUM que se ingresan en la llamada CHECKSUM_AGG está duplicado.

Espero que cualquier respuesta que describa qué causa que CHECKSUM_AGG devuelva 0 explicará estas situaciones también.