我有一个最多3个字符长的字符串,当它第一次创建在SQL Server 2008 R2。

我想用前导零填充它,所以如果它的原始值是“1”,那么新值将是“001”。或者如果它的原始值是“23”,那么新的值是“023”。或者如果它的原始值为124,则新值与原始值相同。

我使用的是SQL Server 2008 R2。如何使用T-SQL做到这一点?


当前回答

我来这里是为了解决如何将我的timezoneoffset转换为一个时区字符串,以便在SQL Server 2008中将日期转换为DATETIMEOFFSET。很恶心,但很有必要。

所以我需要一个方法来处理负数和正数,如果需要,将它们格式化为两个字符,前导为零。Anons的回答让我接近了,但负时区值会显示为0-5而不是所需的-05

所以在他的答案上做了一点调整,这适用于所有时区小时转换

DECLARE @n INT = 13 -- Works with -13, -5, 0, 5, etc
SELECT CASE 
    WHEN @n < 0 THEN '-' + REPLACE(STR(@n * -1 ,2),' ','0') 
    ELSE '+' + REPLACE(STR(@n,2),' ','0') END + ':00'

其他回答

如果字段已经是一个字符串,这将起作用

 SELECT RIGHT('000'+ISNULL(field,''),3)

如果你想让null值显示为000

它可能是一个整数,然后你会想

 SELECT RIGHT('000'+CAST(field AS VARCHAR(3)),3)

根据问题的要求,这个答案只在长度<= 3时有效,如果你想要更大的东西,你需要改变字符串常数和两个整数常数为所需的宽度。例如“0000”和VARCHAR(4)),4

下面是一个更通用的左填充到任何所需宽度的技巧:

declare @x     int     = 123 -- value to be padded
declare @width int     = 25  -- desired width
declare @pad   char(1) = '0' -- pad character

select right_justified = COALESCE(replicate(
                           @pad ,
                           @width-len(convert(varchar(100),@x))
                           ), '')
                       + convert(varchar(100),@x)

但是,如果处理的是负值,并且填充前导为0,那么这种方法和其他建议的技术都不起作用。你会得到这样的结果:

00-123

[可能不是你想要的]

下面是一种正确格式化负数的方法:

declare @x     float   = -1.234
declare @width int     = 20
declare @pad   char(1) = '0'

select right_justified = stuff(
         convert(varchar(99),@x) ,                            -- source string (converted from numeric value)
         case when @x < 0 then 2 else 1 end ,                 -- insert position
         0 ,                                                  -- count of characters to remove from source string
         replicate(@pad,@width-len(convert(varchar(99),@x)) ) -- text to be inserted
         )

应该注意,convert()调用应该指定一个[n]varchar,该varchar有足够的长度来保存经过截断的转换结果。

写这个是因为我有一个特定的长度要求(9)。 仅当输入需要填充时,才使用@pattern填充左侧。 应该总是返回@pattern中定义的长度。

declare @charInput as char(50) = 'input'

--always handle NULL :)
set @charInput = isnull(@charInput,'')

declare @actualLength as int = len(@charInput)

declare @pattern as char(50) = '123456789'
declare @prefLength as int = len(@pattern)

if @prefLength > @actualLength
    select Left(Left(@pattern, @prefLength-@actualLength) + @charInput, @prefLength)
else
    select @charInput

1234年返回输入

虽然这个问题是针对SQL Server 2008 R2的,但如果有人阅读的是2012或更高版本的SQL Server,从那时起,使用FORMAT就变得简单多了。

您可以传递一个标准的数字格式字符串或自定义的数字格式字符串作为format参数(感谢Vadim Ovchinnikov提供的提示)。

对于这个问题,比如一个代码

DECLARE @myInt INT = 1;
-- One way using a standard numeric format string
PRINT FORMAT(@myInt,'D3');
-- Other way using a custom numeric format string
PRINT FORMAT(@myInt,'00#');

输出

001
001

要获得更动态的方法,请尝试以下方法。

declare @val varchar(5)
declare @maxSpaces int
set @maxSpaces = 3
set @val = '3'
select concat(REPLICATE('0',@maxSpaces-len(@val)),@val)