填充带有前导零的字符串,因此在SQL Server 2008中它的长度为3个字符

Sun*_*nil 352 t-sql sql-server

在SQL Server 2008 R2中首次创建时,我有一个最多3个字符的字符串.

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

我正在使用SQL Server 2008 R2.我如何使用T-SQL执行此操作?

Hog*_*gan 626

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

 SELECT RIGHT('000'+ISNULL(field,''),3)
Run Code Online (Sandbox Code Playgroud)

如果你想让空值显示为'000'

它可能是一个整数 - 那么你会想要的

 SELECT RIGHT('000'+CAST(field AS VARCHAR(3)),3)
Run Code Online (Sandbox Code Playgroud)

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

  • 我有一个Char(6)字段,它有一些只有2-3个字符长的值,而上面的字符对我来说不起作用.我必须在'000000'+ ISNULL(FIELD,'')周围添加一个RTRIM才能工作. (8认同)
  • Hogan是的,我得到了,但无论弦不起多长时间,我都有点太忙无法弄清楚为什么,但它的要点是我的CHAR(6)场正好做('000000 '+ ISNULL(字段,''),6)没有工作但是RIGHT(RTRIM('000000'+ ISNULL(字段,'')),6). (3认同)
  • @dwiener你有这种行为,因为char是固定长度的数据类型,所以在你的情况下char(6)意味着6个字符长.如果你的实际值小于6,则用右边的空格填充,这样建议的答案就会产生char(6)的结果. (3认同)
  • 哦,我明白,你在一个编码为字符串的数字的右边有空格. (2认同)
  • @Hogan,是的,但是这个问题是"sql add leading zeros"的top1 google结果,所以我认为对许多人(不使用sqlserver,但google这个问题)知道在其他数据库中可能会有用存在更方便的功能lpad.还是非常感谢. (2认同)

Géz*_*éza 124

虽然问题出在SQL Server 2008 R2上,但是如果有人正在使用2012及更高版本阅读此版本,那么通过使用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#');
Run Code Online (Sandbox Code Playgroud)

输出

001
001
Run Code Online (Sandbox Code Playgroud)

  • 1为001,11为011,111为111 (6认同)
  • 如果输入的数字是111或11,会发生什么? (2认同)
  • 您可以使用“ D3”代替“ 00#”。 (2认同)
  • 尽管看起来不合逻辑,但值得注意的是FORMAT仅适用于数字和日期类型,不适用于varchar。 (2认同)

Ano*_*non 105

安全方法:

SELECT REPLACE(STR(n,3),' ','0')
Run Code Online (Sandbox Code Playgroud)

这样做的好处是返回'***'n <0或n> 999 的字符串,这是一个很好的,明显的输入越界指示.此处列出的其他方法将通过将输入截断为3个字符的子字符串而无声地失败.

  • 该死的,无论谁登陆这个页面都应该帮助这个浮动到顶部! (7认同)
  • 小心这个,字符串会破坏它(并且 OP 要求“填充字符串”)。作品:`SELECT REPLACE(STR('1',3),' ','0')` 中断:`SELECT REPLACE(STR('1A',3),' ','0')`。今天,当用户在输入字符串中输入一个字母而我未能测试该案例时,这让我感到震惊。 (3认同)
  • @Unbound 这就是它的工作原理,海报已经说过了。最好返回 ***,而不是像所有其他提案那样返回截断值,这表明参数是错误的。 (2认同)

Nic*_*rey 30

这是一种更为通用的左填充到任何所需宽度的技术:

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

select right_justified = replicate(
                           @pad ,
                           @width-len(convert(varchar(100),@x))
                           )
                       + convert(varchar(100),@x)
Run Code Online (Sandbox Code Playgroud)

但是,如果您正在处理负值,并使用前导零填充,则此方法或其他建议的技术都不起作用.你会得到这样的东西:

00-123
Run Code Online (Sandbox Code Playgroud)

[可能不是你想要的]

那么......你将不得不跳过一些额外的箍这里有一种方法可以正确地格式化负数:

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
         )
Run Code Online (Sandbox Code Playgroud)

应该注意,convert()调用应该指定[n]varchar足够的长度来保持转换结果的截断.

  • @StenPetrov,谢谢.这一切都取决于你想要完成的事情.我在大型真实世界的生产数据库中学到的一件事就是存在各种不良数据.如果可能的话,我更愿意避开凌晨3点的电话; ^) (2认同)

jah*_*ahu 28

以下是我在SQL Server Express 2012中使用的Hogan答案的变体:

SELECT RIGHT(CONCAT('000', field), 3)
Run Code Online (Sandbox Code Playgroud)

我不是担心该字段是否为字符串,CONCAT而是因为它无论如何都会输出一个字符串.此外,如果字段可以是a NULL,则ISNULL可能需要使用以避免函数获得NULL结果.

SELECT RIGHT(CONCAT('000', ISNULL(field,'')), 3)
Run Code Online (Sandbox Code Playgroud)

  • 据我记得 CONCAT 只是忽略该值,如果它为空,所以第一个工作正常。 (2认同)

小智 20

我总是发现以下方法非常有用.

REPLICATE('0', 5 - LEN(Job.Number)) + CAST(Job.Number AS varchar) as 'NumberFull'
Run Code Online (Sandbox Code Playgroud)


Sal*_*lar 13

使用适合各种情况的此功能.

CREATE FUNCTION dbo.fnNumPadLeft (@input INT, @pad tinyint)
RETURNS VARCHAR(250)
AS BEGIN
    DECLARE @NumStr VARCHAR(250)

    SET @NumStr = LTRIM(@input)

    IF(@pad > LEN(@NumStr))
        SET @NumStr = REPLICATE('0', @Pad - LEN(@NumStr)) + @NumStr;

    RETURN @NumStr;
END
Run Code Online (Sandbox Code Playgroud)

样本输出

SELECT [dbo].[fnNumPadLeft] (2016,10) -- returns 0000002016
SELECT [dbo].[fnNumPadLeft] (2016,5) -- returns 02016
SELECT [dbo].[fnNumPadLeft] (2016,2) -- returns 2016
SELECT [dbo].[fnNumPadLeft] (2016,0) -- returns 2016 
Run Code Online (Sandbox Code Playgroud)


小智 7

尝试使用固定长度。

select right('000000'+'123',5)

select REPLICATE('0', 5 - LEN(123)) + '123'
Run Code Online (Sandbox Code Playgroud)


Ala*_*Dee 5

对于那些想要更新现有数据的人来说,查询是:

update SomeEventTable set eventTime=RIGHT('00000'+ISNULL(eventTime, ''),5)
Run Code Online (Sandbox Code Playgroud)


小智 5

我知道这是一张旧票,但我只是想分享一下:

我发现这段代码提供了解决方案。不确定它是否适用于所有版本的 MSSQL;我有 MSSQL 2016。

declare @value as nvarchar(50) = 23
select REPLACE(STR(CAST(@value AS INT) + 1,4), SPACE(1), '0') as Leadingzero
Run Code Online (Sandbox Code Playgroud)

这将返回“0023”。

STR函数中的4是总长度,包括值。例如,4、23 和 123 在 STR 中都有 4,并且将添加正确数量的零。您可以增加或减少它。无需获取 23 的长度。

编辑:我看到它与@Anon 的帖子相同。