502

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

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

我正在使用 SQL Server 2008 R2。我将如何使用 T-SQL 做到这一点?

4

17 回答 17

827

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

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

如果您希望空值显示为“000”

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

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

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

于 2013-05-26T15:54:23.107 回答
182

虽然问题是针对 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#');

输出

001
001
于 2016-05-04T12:35:44.743 回答
162

安全的方法:

SELECT REPLACE(STR(n,3),' ','0')

这具有返回'***'n < 0 或 n > 999 的字符串的优点,这是一个很好且明显的越界输入指示。此处列出的其他方法将通过将输入截断为 3 个字符的子字符串来静默失败。

于 2015-04-17T21:37:47.293 回答
41

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

SELECT RIGHT(CONCAT('000', field), 3)

而不是担心该字段是否是字符串,我只是CONCAT它,因为它无论如何都会输出一个字符串。此外,如果该字段可以是 a ,则可能需要NULLusing以避免函数获取结果。ISNULLNULL

SELECT RIGHT(CONCAT('000', ISNULL(field,'')), 3)
于 2015-03-27T16:46:50.123 回答
33

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

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)

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

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足够长的长度来保存带有截断的转换结果。

于 2014-07-10T18:23:39.960 回答
27

我一直发现以下方法非常有帮助。

REPLICATE('0', 5 - LEN(Job.Number)) + CAST(Job.Number AS varchar) as 'NumberFull'
于 2014-12-10T15:08:12.407 回答
18

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

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

样本输出

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 
于 2016-05-08T05:47:22.210 回答
6

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

update SomeEventTable set eventTime=RIGHT('00000'+ISNULL(eventTime, ''),5)
于 2014-07-10T16:29:07.457 回答
5

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

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

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

这将返回“0023”。

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

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

于 2018-03-08T11:24:52.867 回答
4

对于整数,您可以使用从 int 到 varchar 的隐式转换:

SELECT RIGHT(1000 + field, 3)
于 2014-04-25T08:13:32.787 回答
3

用固定长度试试这个。

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

select REPLICATE('0', 5 - LEN(123)) + '123'
于 2019-04-09T09:27:47.400 回答
2

对于更动态的方法,试试这个。

declare @val varchar(5)
declare @maxSpaces int
set @maxSpaces = 3
set @val = '3'
select concat(REPLICATE('0',@maxSpaces-len(@val)),@val)
于 2018-10-24T21:28:30.183 回答
2

I had similar problem with integer column as input when I needed fixed sized varchar (or string) output. For instance, 1 to '01', 12 to '12'. This code works:

SELECT RIGHT(CONCAT('00',field::text),2)

If the input is also a column of varchar, you can avoid the casting part.

于 2015-10-21T20:42:36.870 回答
1

简单就是这样

喜欢:

DECLARE @DUENO BIGINT
SET @DUENO=5

SELECT 'ND'+STUFF('000000',6-LEN(RTRIM(@DueNo))+1,LEN(RTRIM(@DueNo)),RTRIM(@DueNo)) DUENO
于 2018-01-12T13:14:32.400 回答
1

写这个是因为我有一个特定长度的要求(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 输入

于 2015-08-19T16:19:53.263 回答
0

我专门来这里研究如何将我的 timezoneoffset 转换为 timezone 字符串,以便在 SQL Server 2008 中将日期转换为 DATETIMEOFFSET。Gross,但必要。

所以我需要一种方法来处理负数和正数,如果需要,将它们格式化为两个带有前导零的字符。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'
于 2020-03-27T16:45:39.533 回答
-1

我创建了这个函数,它适用于 bigint 和一个前导零或其他单个字符(最多返回 20 个字符),并允许结果长度小于输入数字的长度:

create FUNCTION fnPadNum (
  @Num BIGINT --Number to be padded, @sLen BIGINT --Total length of results , @PadChar varchar(1))
  RETURNS VARCHAR(20)
  AS
  --Pads bigint with leading 0's
            --Sample:  "select dbo.fnPadNum(201,5,'0')" returns "00201"
            --Sample:  "select dbo.fnPadNum(201,5,'*')" returns "**201"
            --Sample:  "select dbo.fnPadNum(201,5,' ')" returns "  201"
   BEGIN
     DECLARE @Results VARCHAR(20)
     SELECT @Results = CASE 
     WHEN @sLen >= len(ISNULL(@Num, 0))
     THEN replicate(@PadChar, @sLen - len(@Num)) + CAST(ISNULL(@Num, 0) AS VARCHAR)
     ELSE CAST(ISNULL(@Num, 0) AS VARCHAR)
     END

     RETURN @Results
     END
     GO

     --Usage:
      SELECT dbo.fnPadNum(201, 5,'0')
      SELECT dbo.fnPadNum(201, 5,'*')
      SELECT dbo.fnPadNum(201, 5,' ')
于 2019-10-21T06:51:33.903 回答