2008-09-24 111 views
17

我想知道在SQL中是否有一種簡單的方法將整數轉換爲其二進制表示形式,然後將其存儲爲varchar。SQL Server將整數轉換爲二進制字符串

例如5將被轉換爲「101」並存儲爲varchar。

+7

你想要什麼-5? 「-101」還是「11111111111111111111111111111100」? – Constantin 2008-09-24 16:45:38

回答

15

可以將以下內容編碼爲函數。您需要修剪前導零以滿足您的問題要求。

declare @intvalue int 
set @intvalue=5 

declare @vsresult varchar(64) 
declare @inti int 
select @inti = 64, @vsresult = '' 
while @inti>0 
    begin 
    select @vsresult=convert(char(1), @intvalue % 2)[email protected] 
    select @intvalue = convert(int, (@intvalue/2)), @[email protected] 
    end 
select @vsresult 
+1

這是一個非常糟糕的解決方案。 (1)不需要使用任何循環(2),不需要爲每個功能計算Modulo等任何複雜的數學計算2.您可以根據BITWISE檢查這個簡短的博客以獲得更好的解決方案:http:// ariely .info/Blog/tabid/83/EntryId/169/T-SQL -Decimal-Binary-and-Hexadecimal.aspx – 2015-12-14 09:22:35

2
declare @i int /* input */ 
set @i = 42 

declare @result varchar(32) /* SQL Server int is 32 bits wide */ 
set @result = '' 
while 1 = 1 begin 
    select @result = convert(char(1), @i % 2) + @result, 
     @i = convert(int, @i/2) 
    if @i = 0 break 
end 

select @result 
1
declare @intVal Int 
set @intVal = power(2,12)+ power(2,5) + power(2,1); 
With ComputeBin (IntVal, BinVal,FinalBin) 
As 
    (
    Select @IntVal IntVal, @intVal %2 BinVal , convert(nvarchar(max),(@intVal %2))  FinalBin 
    Union all 
    Select IntVal /2, (IntVal /2) %2, convert(nvarchar(max),(IntVal /2) %2) + FinalBin  FinalBin 
    From ComputeBin 
    Where IntVal /2 > 0 
) 
select FinalBin from ComputeBin where intval = (select min(intval) from ComputeBin); 
+0

我相信你的代碼的最後一行可以改爲 SELECT FinalBin FROM ComputeBin WHERE intval = 1 min在這段代碼中應該總是一個。 此外,此代碼僅適用於正數,即FYI。 – Kevin 2014-12-01 14:34:21

12

其實這個使用普通的舊SQL是非常簡單的。只需使用按位與。我有點驚訝,沒有一個簡單的解決方案在網上發佈(沒有invovle UDFs)。在我的情況下,我真的想檢查位是否打開或關閉(數據來自dotnet eNums)。

因此這裏是給你seperately一起的例子 - 位值和二進制字符串(大聯盟是生產數字只是一個哈克的方式,將工作翻過DBS:

select t.Number 
    , cast(t.Number & 64 as bit) as bit7 
    , cast(t.Number & 32 as bit) as bit6 
    , cast(t.Number & 16 as bit) as bit5 
    , cast(t.Number & 8 as bit) as bit4 
    , cast(t.Number & 4 as bit) as bit3 
    , cast(t.Number & 2 as bit) as bit2 
    ,cast(t.Number & 1 as bit) as bit1 

    , cast(cast(t.Number & 64 as bit) as CHAR(1)) 
    +cast(cast(t.Number & 32 as bit) as CHAR(1)) 
    +cast(cast(t.Number & 16 as bit) as CHAR(1)) 
    +cast(cast(t.Number & 8 as bit) as CHAR(1)) 
    +cast(cast(t.Number & 4 as bit) as CHAR(1)) 
    +cast(cast(t.Number & 2 as bit) as CHAR(1)) 
    +cast(cast(t.Number & 1 as bit) as CHAR(1)) as binary_string 
    --to explicitly answer the question, on MSSQL without using REGEXP (which would make it simple) 
    ,SUBSTRING(cast(cast(t.Number & 64 as bit) as CHAR(1)) 
        +cast(cast(t.Number & 32 as bit) as CHAR(1)) 
        +cast(cast(t.Number & 16 as bit) as CHAR(1)) 
        +cast(cast(t.Number & 8 as bit) as CHAR(1)) 
        +cast(cast(t.Number & 4 as bit) as CHAR(1)) 
        +cast(cast(t.Number & 2 as bit) as CHAR(1)) 
        +cast(cast(t.Number & 1 as bit) as CHAR(1)) 
        , 
        PATINDEX('%1%', cast(cast(t.Number & 64 as bit) as CHAR(1)) 
             +cast(cast(t.Number & 32 as bit) as CHAR(1)) 
             +cast(cast(t.Number & 16 as bit) as CHAR(1)) 
             +cast(cast(t.Number & 8 as bit) as CHAR(1)) 
             +cast(cast(t.Number & 4 as bit) as CHAR(1)) 
             +cast(cast(t.Number & 2 as bit) as CHAR(1)) 
             +cast(cast(t.Number & 1 as bit) as CHAR(1) ) 
        ) 
,99) 


from (select 1 as Number union all select 2 union all select 3 union all select 4 union all select 5 union all select 6 
    union all select 7 union all select 8 union all select 9 union all select 10) as t 

生成此結果:

num bit7 bit6 bit5 bit4 bit3 bit2 bit1 binary_string binary_string_trimmed 
1 0 0 0 0 0 0 1 0000001   1 
2 0 0 0 0 0 1 0 0000010   10 
3 0 0 0 0 0 1 1 0000011   11 
4 0 0 0 1 0 0 0 0000100   100 
5 0 0 0 0 1 0 1 0000101   101 
6 0 0 0 0 1 1 0 0000110   110 
7 0 0 0 0 1 1 1 0000111   111 
8 0 0 0 1 0 0 0 0001000   1000 
9 0 0 0 1 0 0 1 0001001   1001 
10 0 0 0 1 0 1 0 0001010   1010 
+0

+1表達式可用作計算列 – Gabe 2012-07-24 00:55:07

0

這個如何...

SELECT number_value 
,MOD(number_value/32768, 2) AS BIT15 
,MOD(number_value/16384, 2) AS BIT14 
,MOD(number_value/8192, 2) AS BIT13 
,MOD(number_value/4096, 2) AS BIT12 
,MOD(number_value/2048, 2) AS BIT11 
,MOD(number_value/1024, 2) AS BIT10 
,MOD(number_value/ 512, 2) AS BIT9 
,MOD(number_value/ 256, 2) AS BIT8 
,MOD(number_value/ 128, 2) AS BIT7 
,MOD(number_value/ 64, 2) AS BIT6 
,MOD(number_value/ 32, 2) AS BIT5 
,MOD(number_value/ 16, 2) AS BIT4 
,MOD(number_value/ 8, 2) AS BIT3 
,MOD(number_value/ 4, 2) AS BIT2 
,MOD(number_value/ 2, 2) AS BIT1 
,MOD(number_value  , 2) AS BIT0 
FROM your_table; 
+0

MOD不是sqlserver – 2016-03-29 09:10:21

0

我相信是t他的方法簡化了其他人提出的其他想法。它使用按位運算和帶有CTE的FOR XML技巧來生成二進制數字。

DECLARE @my_int INT = 5 

;WITH CTE_Binary AS 
(
    SELECT 1 AS seq, 1 AS val 
    UNION ALL 
    SELECT seq + 1 AS seq, power(2, seq) 
    FROM CTE_Binary 
    WHERE 
     seq < 8 
) 
SELECT 
(
    SELECT 
     CAST(CASE WHEN B2.seq IS NOT NULL THEN 1 ELSE 0 END AS CHAR(1)) 
    FROM 
     CTE_Binary B1 
    LEFT OUTER JOIN CTE_Binary B2 ON 
     B2.seq = B1.seq AND 
     @my_int & B2.val = B2.val 
    ORDER BY 
     B1.seq DESC 
    FOR XML PATH('') 
) AS val 
0

我用下面的ITVF函數從十進制轉換爲二進制 ,因爲它是你不需要「愁」關於多次讀取優化程序執行內聯函數。

 CREATE FUNCTION dbo.udf_DecimalToBinary 
    (
     @Decimal VARCHAR(32) 
    ) 

    RETURNS TABLE AS RETURN 

    WITH Tally (n) AS 
    (
     --32 Rows 
     SELECT TOP 30 ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 
     FROM (VALUES (0),(0),(0),(0)) a(n) 
     CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0)) b(n) 

    ) 

    , Anchor (n, divisor , Result) as 
    (
    SELECT t.N , 
      CONVERT(BIGINT, @Decimal)/POWER(2,T.N) , 
      CONVERT(BIGINT, @Decimal)/POWER(2,T.N) % 2 
    FROM Tally t 
    WHERE CONVERT(bigint,@Decimal) >= POWER(2,t.n) 
    ) 


    SELECT TwoBaseBinary = '' + 
     (SELECT Result 
      FROM Anchor 
      ORDER BY N DESC 
      FOR XML PATH ('') , TYPE).value('.','varchar(200)') 

    /*How to use*/ 
    SELECT TwoBaseBinary 
    FROM dbo.udf_DecimalToBinary ('1234') 

    /*result -> 10011010010*/ 
0
with t as (select * from (values (0),(1)) as t(c)), 

t0 as (table t), 
t1 as (table t), 
t2 as (table t), 
t3 as (table t), 
t4 as (table t), 
t5 as (table t), 
t6 as (table t), 
t7 as (table t), 
t8 as (table t), 
t9 as (table t), 
ta as (table t), 
tb as (table t), 
tc as (table t), 
td as (table t), 
te as (table t), 
tf as (table t) 

select '' || t0.c || t1.c || t2.c || t3.c || t4.c || t5.c || t6.c || t7.c || t8.c || t9.c || ta.c || tb.c || tc.c || td.c || te.c || tf.c as n 
from t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,ta,tb,tc,td,te,tf 
order by n 

limit 1 offset 5 

標準SQL(PostgreSQL中測試)。

0

在SQL Server中,你可以嘗試像下面的示例:

DECLARE @Int int = 321 

SELECT @Int 
,CONCAT 
(CAST(@Int & power(2,15) AS bit) 
,CAST(@Int & power(2,14) AS bit) 
,CAST(@Int & power(2,13) AS bit) 
,CAST(@Int & power(2,12) AS bit) 
,CAST(@Int & power(2,11) AS bit) 
,CAST(@Int & power(2,10) AS bit) 
,CAST(@Int & power(2,9)  AS bit) 
,CAST(@Int & power(2,8)  AS bit) 
,CAST(@Int & power(2,7)  AS bit) 
,CAST(@Int & power(2,6)  AS bit) 
,CAST(@Int & power(2,5)  AS bit) 
,CAST(@Int & power(2,4)  AS bit) 
,CAST(@Int & power(2,3)  AS bit) 
,CAST(@Int & power(2,2)  AS bit) 
,CAST(@Int & power(2,1)  AS bit) 
,CAST(@Int & power(2,0)  AS bit)) AS BitString 

,CAST(@Int & power(2,15) AS bit) AS BIT15 
,CAST(@Int & power(2,14) AS bit) AS BIT14 
,CAST(@Int & power(2,13) AS bit) AS BIT13 
,CAST(@Int & power(2,12) AS bit) AS BIT12 
,CAST(@Int & power(2,11) AS bit) AS BIT11 
,CAST(@Int & power(2,10) AS bit) AS BIT10 
,CAST(@Int & power(2,9)  AS bit) AS BIT9 
,CAST(@Int & power(2,8)  AS bit) AS BIT8 
,CAST(@Int & power(2,7)  AS bit) AS BIT7 
,CAST(@Int & power(2,6)  AS bit) AS BIT6 
,CAST(@Int & power(2,5)  AS bit) AS BIT5 
,CAST(@Int & power(2,4)  AS bit) AS BIT4 
,CAST(@Int & power(2,3)  AS bit) AS BIT3 
,CAST(@Int & power(2,2)  AS bit) AS BIT2 
,CAST(@Int & power(2,1)  AS bit) AS BIT1 
,CAST(@Int & power(2,0)  AS bit) AS BIT0 
1

這是一個有點變化的accepted answer from Sean,因爲我發現它的限制,只允許在輸出數字的硬編碼數。在我的日常使用中,我發現它只能獲得最高1位數,或者指定我期待的數字。它會自動用0填充邊,這樣它就可以連接到8,16或任何你想要的位數。

Create function f_DecimalToBinaryString 
    (
     @Dec int, 
     @MaxLength int = null 
    ) 
Returns varchar(max) 
as Begin 

    Declare @BinStr varchar(max) = ''; 

    -- Perform the translation from Dec to Bin 
    While @Dec > 0 Begin 

     Set @BinStr = Convert(char(1), @Dec % 2) + @BinStr; 
     Set @Dec = Convert(int, @Dec /2); 

    End; 

    -- Either pad or trim the output to match the number of digits specified. 
    If (@MaxLength is not null) Begin 
     If @MaxLength <= Len(@BinStr) Begin -- Trim down 
      Set @BinStr = SubString(@BinStr, Len(@BinStr) - (@MaxLength - 1), @MaxLength); 
     End Else Begin -- Pad up 
      Set @BinStr = Replicate('0', @MaxLength - Len(@BinStr)) + @BinStr; 
     End; 
    End; 

    Return @BinStr; 

End;