问题
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.
回答1:
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
回答2:
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.
回答3:
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
来源:https://stackoverflow.com/questions/41439509/sql-server-how-to-convert-binary-back-to-int