2017-01-03 2 views
0

Admin de notre IS stocké 8 drapeaux comme '00010000' (seulement vrai et faux) à SQL Server comme binary(2). Dans ce format, les données ont des valeurs comme '0x1000'.SQL Server: comment convertir binaire en int

Est-il possible de convertir ce fichier binaire en '00010000'?

Convert, Cast, Substring ne fonctionnent pas.

+0

Est-ce que '0x1000' a vraiment la même valeur que '00010000'? – jarlh

+0

Oui. Quand j'ai des valeurs de IS '00010000' alors en SQL est la valeur '0x1000'. Mais si j'ai par exemple '00110000' alors la valeur est '0x3000'. –

Répondre

0

Requête renvoie nombre hexadécimal (0x ... - il est hexadécimal) comme masque de bits

CREATE TABLE #Temp(
    Test VARBINARY(2) 
) 

INSERT #Temp 
VALUES 
    (0x1001), 
    (0x3001), 
    (0x5000), 
    (0x6000), 
    (0xf000), 
    (0xf250) 

SELECT *, REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(
    CONVERT(VARCHAR(32), Test, 2) 
    , '0', '0000') 
    , '1', '0001') 
    , '2', '0010') 
    , '3', '0011') 
    , '4', '0100') 
    , '5', '0101') 
    , '6', '0110') 
    , '7', '0111') 
    , '8', '1000') 
    , '9', '1001') 
    , 'a', '1010') 
    , 'b', '1011') 
    , 'c', '1100') 
    , 'd', '1101') 
    , 'e', '1110') 
    , 'f', '1111') 
FROM #Temp 

DROP TABLE #Temp 
0

Vos données d'origine sont probablement perdues. Lorsque vous convertissez un nombre en binaire dans SQL, il n'y a qu'une quantité limitée "d'espace" pour stocker ces données, l'espace est déterminé par la taille d'octet du champ, dans ce cas 2.

Le problème se produit lorsque le les données sont sauvegardées dans la base de données, en utilisant un binaire (2) signifie que les données sont tronquées lors de l'enregistrement, ce qui signifie que vous avez perdu au moins les 4 premiers "indicateurs" dans vos données. (les 4 chiffres au début de votre numéro binaire).

par exemple, ci-dessous montre ce que les magasins SQL pour le nombre 10010010 en binaire 6, 4 et 2.

Binary(6) - 0x00000098BD9A 
Binary(4) - 0x0098BD9A 
Binary(2) - 0xBD9A 

comme vous pouvez le voir en utilisant les moyens binaires 2 vous perdez les données de votre numéro. Cela est parti et ne peut pas être récupéré en utilisant le DB (sauf si vous enregistrez les journaux de transactions, qui, étant donné que vous avez un DBA stockant des valeurs booléennes comme un bloc de 8 bits utilisant un champ binaire (2) je doute que vous avez). Donc désolé de le dire mais vous ne pouvez tout simplement pas faire ce dont vous avez besoin, et c'est celui qui pensait utiliser binary (2) pour un nombre à 8 chiffres était une bonne idée et n'a pas testé leur décision à blâmer.

+0

Donc il doit y avoir d'autres codes codés avant de l'insérer dans sql si j'obtiens le résultat '0x9200' quand je teste ton exemple '10010010'? Cela expliquerait pourquoi ils sont capables de récupérer des données dans le «tableau» d'origine. –

+0

Si vous avez un programme qui est capable de traduire les valeurs stockées dans la valeur de 8 chiffres d'origine avec succès 100% du temps alors, oui, il doit y avoir une couche de traduction entre l'entrée et la base de données. – Kamikazi

0

Oui vous pouvez

BINARY(2) signifie 2 octets, donc 16 bits

0x3000 = '0011000000000000'

declare @v int = 0x3000 

;WITH 
T AS ( SELECT NULL N UNION ALL SELECT NULL), 
N as (
    SELECT ROW_NUMBER() OVER (ORDER BY T2.N) N 
    FROM T T2, T T4, T T8, T T16 
), 
V AS (
    select N, POWER(2,N-1) P, CAST(@v as binary(2)) b2, @v V 
    from N 
), 
B AS (
    SELECT N, B2, CAST((V/P) % 2 AS char(1)) B 
    from V 
) 
SELECT B2, [16]+[15]+[14]+[13]+[12]+[11]+[10]+[9]+[8]+[7]+[6]+[5]+[4]+[3]+[2]+[1] BASE2 
FROM B 
PIVOT (MIN(B) FOR N IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16])) P 

sortie

B2  BASE2 
0x3000 0011000000000000