2008-09-24 140 views
17

Tôi đã tự hỏi nếu có một cách dễ dàng trong SQL để chuyển đổi một số nguyên để đại diện nhị phân của nó và sau đó lưu trữ nó như là một varchar.SQL Server Chuyển đổi số nguyên thành chuỗi nhị phân

Ví dụ 5 sẽ được chuyển thành "101" và được lưu trữ dưới dạng varchar.

+7

Bạn muốn gì cho -5? "-101" hoặc "11111111111111111111111111111100"? – Constantin

Trả lời

15

Sau đây có thể được mã hóa thành một hàm. Bạn sẽ cần phải cắt bỏ các số 0 đầu để đáp ứng các yêu cầu của câu hỏi của bạn.

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

Đây là một giải pháp rất xấu. (1) Không cần sử dụng bất kỳ vòng lặp nào (2) không cần phải thực hiện bất kỳ phép tính phức tạp nào như tính toán Modulo cho mỗi nguồn 2. Bạn có thể kiểm tra blog ngắn này để có giải pháp tốt hơn dựa trên BITWISE: http: // ariely .info/Blog/tabid/83/EntryId/169/T-SQL-Chuyển đổi-giữa-Thập phân-nhị phân-và-Hexadecimal.aspx –

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

Tôi tin rằng dòng cuối cùng của mã của bạn có thể được thay đổi thành CHỌN FinalBin FROM ComputeBin WHERE intval = 1 Min phải luôn là một trong mã này. Ngoài ra, mã này chỉ hoạt động với số dương, FYI. – Kevin

12

Trên thực tế đây là thực sự đơn giản sử dụng đồng bằng SQL cũ. Chỉ cần sử dụng bit ANDs. Tôi có một chút ngạc nhiên khi không có một giải pháp đơn giản nào được đăng trực tuyến (điều đó đã không giải thích UDF). Trong trường hợp của tôi, tôi thực sự muốn kiểm tra xem bit đã được bật hay tắt (dữ liệu đến từ dotnet eNums).

Theo đó đây là một ví dụ mà sẽ cung cấp cho bạn một cách riêng biệt và với nhau - các giá trị bit và chuỗi nhị phân (công đoàn lớn chỉ là một cách hacky sản xuất số mà sẽ làm việc accross 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 

Tạo kết quả này :

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 cho biểu thức tôi có thể sử dụng làm cột được tính – Gabe

0

Làm thế nào về vấn đề này ...

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 không phải là sqlserver –

0

tôi tin rằng t phương pháp của ông đơn giản hóa rất nhiều ý tưởng khác mà những người khác đã trình bày. Nó sử dụng số học bitwise cùng với thủ thuật FOR XML với một CTE để tạo ra các chữ số nhị phân.

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

tôi đã sử dụng sau ITVF chức năng để chuyển đổi từ thập phân để Binary vì nó là một hàm inline bạn không cần phải "lo lắng" về nhiều nội dung đã được thực hiện bởi tôi ưu hoa.

 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 

Chuẩn SQL (thử nghiệm trong PostgreSQL).

0

Mở SQL Server, bạn có thể thử một cái gì đó giống như các mẫu dưới đây:

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

Dưới đây là một chút của một sự thay đổi đến accepted answer from Sean, kể từ khi tôi tìm thấy nó giới hạn chỉ cho phép một số mã hóa cứng các chữ số ở đầu ra . Trong việc sử dụng hàng ngày của tôi, tôi thấy hữu ích hơn nếu chỉ nhận được tối đa 1 chữ số hoặc chỉ định số lượng chữ số mà tôi mong đợi. Nó sẽ tự động pad bên với 0s, để nó dòng lên đến 8, 16, hoặc bất cứ số bit bạn muốn.

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; 
Các vấn đề liên quan