2012-03-21 11 views
1

私は謝罪していないようです。私はT-SQLを3年ほどしか書いていませんが、ほとんどが独学です。私の仕事では、月の日の値をビットマスクで保存します。例えば。 1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxは1に変換され、12345678910111213141516171819202122232425262728293031は2147483647に変換されます。int値を数値と 'x'文字を含むvarchar(64)に変換します。私は別のpostから次のコードをいくつかの微調整と似ていますが、データを後方に提供します(左から右への代わりに右から左へ)。ビット単位のint値を月の日のマスクに変換する

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 Replace(@result,'0','X') 

また、すべての文字を提供するわけではありません。 31文字すべてを埋め戻す必要があります。

私もRob Farley's Simple Recursive CTEでプレイしました。

+3

"12345678910111213141516171819202122232425262728293031は2147483647に変換されます" - どのように?確かにビットマスクは1と0だけでしょうか? – Phil

+0

@Phil 53文字の文字列 '12345678910111213141516171819202122232425262728293031'には、月の31日がすべて連結されています。バイナリ= '2147483647'の' 1111111111111111111111111111111'を10進数で表します。 –

+1

ああ、そうだ。すぐには分かりませんでした! – Phil

答えて

2

その後、varchar(32)値にビットを連結し、ビットに@iを分割する数値テーブルを使用することができます。

DECLARE @i int = 42; 

WITH bits AS (
    SELECT 
    number, 
    B = CASE @i & POWER(2, number - 1) WHEN 0 THEN 'x' ELSE '1' END 
    FROM master..spt_values 
    WHERE type = 'P' 
    AND number BETWEEN 1 AND 31 
) 
SELECT CAST((
    SELECT '' + B 
    FROM bits 
    ORDER BY number 
    FOR XML PATH ('') 
) AS varchar(32)) 

結果:

-------------------------------- 
x1x1x1xxxxxxxxxxxxxxxxxxxxxxxxx 

このソリューションは、master..spt_valuesと呼ばれるシステムテーブルを使用しています数値表として、しかしそれは決してgenerateに悪い考えではなく、あなたの代わりに自分自身を使用してください。

+0

ありがとう!私はお詫びします、私はちょうどこれを見ました...私はそれに応答されて警告されていない!私は最初の可能性のある機会にこれを試みます。 – Jacrys

関連する問題