Usando a função CHECKSUM para comparar dados entre tabelas.

Boa noite pessoal.

Dica rápida sobre uma das utilidades da função CHECKSUM() do SQL Server, uma função pouco falada mas muito útil no dia-a-dia.

A função CHECKSUM() do SQL Server gera um HASH VALUE sobre os valores passados, esse valor é gerado internamente pelo SQL Server.

Um exemplo simples do CHECKSUM:

 SELECT CHECKSUM(‘CHURRASCO’)

———–
-77117179

(1 row(s) affected)

A ideia é que sempre que eu executar esse mesmo SELECT me retorne sempre esse valor de -77117179, esse valor pode variar de acordo com algumas configurações de ambiente para ambiente.

Sabendo então que o CHECKSUM me retorna sempre o mesmo valor para um determinado parâmetro, posso então utiliza-lo para calcular o HASH VALUE da linha de uma tabela, como veremos no exemplo abaixo.

 

IF (DB_ID(‘DB_CHECKSUM’)) IS NOT NULL
DROP DATABASE DB_CHECKSUM

GO
CREATE DATABASE DB_CHECKSUM

GO

USE DB_CHECKSUM
GO

CREATE TABLE TB_CHECK1 (CAMPO1 INT IDENTITY(1,1), CAMPO2 CHAR(20) DEFAULT (‘COCA COLA’), CAMPO3 VARCHAR(3000) DEFAULT(‘BATATA FRITA’))
GO

INSERT INTO TB_CHECK1 DEFAULT VALUES
GO 100

SELECT SUM(CAST(CHECKSUM(*) AS BIGINT)) FROM TB_CHECK1
——————–
27082577192

(1 row(s) affected)

Como podemos ver o valor ‘27082577192’ foi gerado com base na soma do CHECKSUM de todos os dados compostos por todas as colunas da tabela TB_CHECK1, o que acontece se existir uma tabela idêntica a essa? Vamos ver.

 

CREATE TABLE TB_CHECK2 (CAMPO1 INT IDENTITY(1,1), CAMPO2 CHAR(20) DEFAULT (‘COCA COLA’), CAMPO3 VARCHAR(3000) DEFAULT(‘BATATA FRITA’))
GO

INSERT INTO TB_CHECK2 DEFAULT VALUES
GO 100

SELECT SUM(CAST(CHECKSUM(*) AS BIGINT)) FROM TB_CHECK2
SELECT SUM(CAST(CHECKSUM(*) AS BIGINT)) FROM TB_CHECK1

SELECT
(SELECT SUM(CAST(CHECKSUM(*) AS BIGINT)) FROM TB_CHECK2) TB1,
(SELECT SUM(CAST(CHECKSUM(*) AS BIGINT)) FROM TB_CHECK1) TB2,
IIF((SELECT SUM(CAST(CHECKSUM(*) AS BIGINT)) FROM TB_CHECK2)=
(SELECT SUM(CAST(CHECKSUM(*) AS BIGINT)) FROM TB_CHECK1),’EQUAL’,’NOT EQUAL’) TB2

checksum

Como podemos ver foi criado a tabela TB_CHECK2 idêntica a tabela TB_CHECK1 com os mesmos dados e temos o resultado acima.

E seu eu atualizar uma linha da minha tabela?

 

UPDATE TB_CHECK1 SET CAMPO2 = ‘SPRITE’ WHERE CAMPO1= 10

 

checksum2

Podemos ver que existe uma diferença entre os valores gerados, com isso sabemos que as duas tabelas não possuem os mesmos dados.

 

SELECT * FROM (
SELECT CHECKSUM(*) CHK,CAMPO1 FROM TB_CHECK1
)TB1 LEFT JOIN (
SELECT CHECKSUM(*) CHK,CAMPO1 FROM TB_CHECK2
)TB2 ON TB1.CHK = TB2.CHK WHERE TB2.CHK IS NULL

CHK            CAMPO1           CHK             CAMPO1
———– ———– ———– ———–
903141930       10                NULL               NULL

(1 row(s) affected)

Com um simples LEFT JOIN podemos encontrar quem está fora dos trilhos.

Bom então posso confiar 100% no CHECKSUM ?

Como o CHECKSUM retorna um valor inteiro ele é limitado a gerar um valor dentro da capacidade do tipo de dados INT e existe uma pequena chance do CHECKSUM gerar valores iguais para parâmetros diferente, a Microsoft pede para considerar o uso da função HashBytes que pode gerar HASHs maiores e mais complexas de acordo com o algoritmo escolhido.

Exemplo de um HashBytes:

 SELECT HASHBYTES(‘MD5′,’FEIJOADA’)

———————————————————————–
0x58371F0D2C39B5B15D57ED8632B4B272

(1 row(s) affected)

 

Não reparem nos valores utilizados de exemplo, não sou gordo, apenas coincidência de todas serem referência para “gordices”.

Espero que tenham gostado da dica, deixe sua opinião e até a próxima.

 

Referências:

CHECKSUM

https://msdn.microsoft.com/en-us/library/ms189788.aspx

HASHBYTES

https://msdn.microsoft.com/en-us/library/ms174415.aspx

 

Reginaldo Silva

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s