2016-12-18 5 views
3

Dans SQL Server, vous pouvez utiliser FLOAT ou REAL pour stocker des valeurs à virgule flottante dont le format de stockage est défini par la norme IEEE 754. Pour les valeurs à virgule fixe, nous pouvons utiliser le type DECIMAL (qui a un synonyme NUMERIC). Cependant, je ne suis pas sûr de savoir comment SQL Server stocker DECIMAL valeurs en interne. Par exemple, si je définis une table et insérer une ligne comme celle-ci:Comment SQL Server stocke-t-il les valeurs de type décimal en interne?

IF OBJECT_ID('dbo.test_number_types') IS NOT NULL DROP TABLE dbo.test_number_types; 
CREATE TABLE dbo.test_number_types 
(
    id INT IDENTITY(1, 1), 
    c1 NUMERIC(5, 4) 
) 
GO 

INSERT INTO dbo.test_number_types(c1)VALUES(5.7456); 

Lorsque j'utilise la commande DBCC PAGE pour vérifier comment SQL Server stocke le numéro 5,7456, je suis arrivé ceci:

01 70 E0 00 00 

Cet hex chaîne devrait utiliser peu endian. Je ne peux pas comprendre comment SQL Server tourne 5.7456 en 01 70 E0 00 00 et comment il décide combien d'octets sont pour la partie intégrale et combien d'octets sont pour les parties décimales. Quelqu'un peut-il aider?


BTW, j'ai vérifié le livre "SQL Server 2012 Internals". Il y a un chapitre dédié au stockage de type de données. Mais il semble DECIMAL le stockage de type n'est pas mentionné dans le livre.

+0

Astuce: BCD, décimal codé en binaire (https: // fr. wikipedia.org/wiki/Binary-coded_decimal). Je ne peux pas jurer que c'est ainsi que SQL Server stocke réellement la valeur, mais c'est une méthode très typique pour stocker des valeurs de points fixes dans d'autres langues. –

+0

Merci Gordon pour le lien. Je regarderai. –

+0

@GordonLinoff J'ai essayé, ne semble pas l'encodage BCD. –

Répondre

5

Le commentaire de Martin's Smith vous donne l'indice. SQL Server n'utilise pas BCD. Il stocke les données sous la forme d'un nombre entier, sans la décimale (ce qu'il peut faire car la décimale est stockée dans les métadonnées de la colonne). Ainsi, 5.7456 est stocké sous la forme 57456 ou 0xE070. Après l'infâme échange d'octets de SQL, ceci est transformé en 70 E0 00 00.

Le premier signe 01 est le signe. 01 est utilisé pour les nombres positifs; 00 pour les négatifs.

(Cependant, je dois demander - pourquoi avez-vous besoin de ce cas d'utilisation typique, vous ne devriez jamais avoir à se soucier de internals de SQL Server?)

+0

Merci encore Hugo! Je veux savoir c'est parce que je lis le livre "SQL Server 2012 Internals" et j'ai trouvé le type DECIMAL n'est pas mentionné. Juste par curiosité. –