将逐位int值转换为一个月中的某一天掩码



如果我看起来不知道,我很抱歉。我只写T-SQL大约3年了,大部分都是自学成才的。在我的工作中,我们将每个月的日期值存储在比特掩码中。例如,1xxxxxxxxxxxxxxxxxxxxxxxxx转换为1,12345678910111213141516171819202122232425262728293031转换为2147483647。我想要/需要做的是将int值转换为包含数字和"x"字符的varchar(64)。我在这里的另一篇文章中有下面的代码,它做了一些类似的调整,但它向后提供了数据(从右到左[对于二进制应该是这样],而不是从左到右)。

    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的简单递归CTE。

您可以使用数字表将@i拆分为位,然后将位连接为varchar(32)值:

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的系统表作为数字表,但生成并使用自己的表从来都不是一个坏主意。

最新更新