Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

SQL Server : Différence de calcul du CHECKSUM sur SQL Server 2005 et 2008 ou sur les plateformes 32 bits et 64 bits ?

Ayant eu vent d'une différence de comportement entre version (2005 et 2008) ou entre plateforme de SQL Server (32 bits et 64 bits) de la fonction CHECKSUM, je me suis dit qu'il fallait creuser un peu.

En effet il n'est pas impossible qu'il y ai une telle différence, mais généralement, soit elle est annoncée à l'avance, soit c'est purement et simplement un bug. Il y a déjà des précèdent par exemple le calcul des Hash entre la plateforme x64 et x86 :

string s = "azerty" ;

Console.WriteLine(s.GetHashCode().ToString());

Donne en 32 bits:

765360530

Et en 64 bits:

1423019289

Sur SQL Server, l'équipe de développement essaye de conserver un comportement similaire quelques soit la plateforme, même s'il peut arriver qu'une fonction renvoie des valeurs légèrement différente d'une version ou plateforme à l'autre. Mais ces comportement sont souvent passés à la loupe, car imaginez un Hash Index (http://blogs.codes-sources.com/christian/archive/2009/09/22/sql-server-hash-index-ou-comment-indexer-de-tr-s-grosses-colonnes.aspx) qui se retrouverait avec des valeurs différentes suite à une montée de version ou un changement de serveur lors d'un basculement, il y aurait de quoi s'affoler !

Le calcul du CHECKSUM sur SQL Server se fera par :

SELECT CHECKSUM('azerty')

Le résultat obtenu est clairement différent de celui .Net, ce qui confirme un algorithme différent.

139376054

A noter une particularité lié au type de données dans le calcul de la fonction précédente. En effet, si je mets ma chaîne en type Unicode (N majuscule précédent celle-ci):

SELECT CHECKSUM(N'azerty')

On obtient alors un résultat différent :

-1258351920

Passons aux tests sur des versions / plateforme différentes, avec la requête suivant, renvoyant le CHECKSUM, la version et la plateforme (simplifié, je n'ai pas inlus le IA64... je n'ai pas de tels serveurs) :

select CHECKSUM('azerty'), SERVERPROPERTY('ProductVersion'), CASE WHEN PATINDEX('%X86%', @@VERSION) != 0 THEN '32 bits' ELSE '64 bits' END

La requête précédente est exécutée sur un ensemble de serveurs équipés de versions et plateformes hétérogènes pour se faire une idée du résultat.

Voici les resulats :

CHECKSUM

VERSION

Plateforme

139376054

10.0.2734.0

64 bits

139376054

10.0.2746.0

64 bits

139376054

9.00.4266.00

64 bits

139376054

10.0.2746.0

64 bits

139376054

10.0.2734.0

64 bits

139376054

10.0.2734.0

64 bits

139376054

10.0.2734.0

64 bits

139376054

10.0.2734.0

64 bits

139376054

10.0.2746.0

64 bits

139376054

10.0.2734.0

64 bits

-1258351920

9.00.4220.00

32 bits

139376054

10.0.2734.0

64 bits

139376054

10.0.2746.0

64 bits

139376054

10.0.2746.0

64 bits

139376054

10.0.2734.0

64 bits

139376054

10.0.2746.0

64 bits

139376054        

9.00.4207.00

32 bits

Seule une ligne est différente des autres. On pourrait conclure à une différence de comportement de SQL Server 2005 en 32 bits, mais non. Une autre ligne montre cette même combinaison de version et plateforme avec un résultat identique.

D'où vient alors la différence ? Si vous avez suivi mes 2 exemples en SQL, vous avez vu que le CHECKSUM diffère quand le type de la chaîne change… Or il y a un paramètre qui a une grosse incidence sur çà : Le classement (COLLATE).

Si on ajoute à la liste de notre SELECT :

SERVERPROPERTY('Collation')

On obtient la liste (j'ai ajouté 2 serveurs en plus par rapport à la requête précédente, pour confirmer le comportement,):

CHECKSUM

Version

Plateforme

Classement Serveur

139376054

10.0.2734.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

9.00.4266.00

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2746.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2746.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2734.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2734.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2746.0

64 bits

SQL_Latin1_General_CP1_CI_AS

-1258351920

9.00.4220.00

32 bits

Latin1_General_CI_AS

139376054

10.0.2734.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2746.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2734.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2734.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2734.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2746.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2746.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

10.0.2734.0

64 bits

SQL_Latin1_General_CP1_CI_AS

139376054

9.00.4207.00

32 bits

SQL_Latin1_General_CP1_CI_AS

-1258351920

10.0.2734.0

64 bits

Latin1_General_100_CI_AS

139376054

10.25.9084.0

(SQL Azure)

64 bits

SQL_Latin1_General_CP1_CI_AS

-1258351920

10.0.2531.0

64 bits

French_CI_AS

-1258351920

10.50.1352.12

(SQL Server 2008 R2 CTP Nov.)

64 bits

Latin1_General_100_CI_AS

Cette fois ci la différence est flagrante, ce n'est pas de la plateforme ou de la version de SQL Server que dépend le calcul de CHECKSUM, mais du classement courant ! Plus précisément de la différence entre les classements Windows (Latin1_General, Latin1_General_100 et …) et les classements SQL (SQL_Latin1_General_CP1). Le comportement du classement Windows est d'implicitement convertir les constantes de chaîne de caractères en chaîne Unicode.

Pour confirmer ce comportement, et accessoirement déterminer si c'est le classement du serveur ou celui de la base de données qui est pris en compte (et là on croise les doigts pour que ce soit le second, sinon gare aux problèmes dans ses bases de données), on va essayer un autre script :

CREATE DATABASE x COLLATE Latin1_General_CI_AS
GO

CREATE DATABASE y COLLATE SQL_Latin1_General_CP1_CI_AS
GO

USE x
GO

SELECT CHECKSUM('azerty')
GO

USE y
GO

SELECT CHECKSUM('azerty')
GO

Je vous laisse découvrir le résultat par vous-même. Disons que c'est celui que l'on pouvait espérer dans le meilleur des cas : c'est le classement de la base de données courante qui est pris en considération.

Faites donc très attention à la base de données courante lors des calculs de CHECKSUM. Cependant, la plateforme et la version ne sont pas en cause dans ces formes de calculs... Heureusement j'aurais auguré le pire pour certaines migrations et même backup/restore de certaines applications si tel n'avait pas été le cas.

Bonne somme de contrôle…

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Publié mercredi 16 décembre 2009 15:39 par christian
Classé sous : ,

Commentaires

Pas de commentaires
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01