SQL Server : how to convert binary back to int

4.4k views Asked by At

Admin of our IS stored 8 flags like '00010000' (only true and false) to SQL Server as binary(2). In this format data has values like '0x1000'.

Is possible to convert this binary back to '00010000' ?

Convert, Cast, Substring don't work.

3

There are 3 answers

0
Denis Rubashkin On BEST ANSWER

Query returns hexadecimal number (0x... - it is hexadecimal) as its bit mask

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
MtwStark On

Yes you can

BINARY(2) means 2 bytes, so 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

output

B2      BASE2
0x3000  0011000000000000
3
Kamikazi On

Your original data is most likely lost. When you convert a number to binary in SQL there is only a limited amount of "space" to store that data, the space is determined by the byte size of the field, in this case 2.

The issue occurs when the data is saved to the database, using a binary(2) means that data is truncated when saved, meaning that you have lost at least the 4 first "flags" in your data. (the 4 numbers at the start of your binary number).

for example, the below shows what SQL stores for the number 10010010 in binary 6, 4 and 2.

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

as you can see using binary 2 means you lose data from your number. That is gone and cannot be retrieved using the DB (unless you save transaction logs, which, given you have a DBA storing boolean values as an 8 bit block using a binary(2) field I doubt you have). So sorry to say this but you simply cannot do what you need to, and it's whoever thought using binary(2) for an 8 digit number was a good idea and then didn't test their decision that is to blame.