2008-09-24 78 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;