在SQL Server 2008中用前导零填充字符串,使其长度为3个字符

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

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

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

1138050 次浏览

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

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

如果你想让null值显示为000

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

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

根据问题的要求,这个答案只适用于长度<= 3,如果你想要更大的东西,你需要改变字符串常数和两个整数常数为所需的宽度。如# EYZ0

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

SELECT RIGHT(1000 + field, 3)

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

update SomeEventTable set eventTime=RIGHT('00000'+ISNULL(eventTime, ''),5)

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

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,以保存经过截断的转换结果。

我一直认为下面的方法非常有用。

REPLICATE('0', 5 - LEN(Job.Number)) + CAST(Job.Number AS varchar) as 'NumberFull'

下面是我在SQL Server Express 2012中使用的Hogan回答的一个变体:

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

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

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

安全方法:

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

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

写这个是因为我有一个特定的长度要求(9)。 仅当输入需要填充时,才使用@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年返回输入

当我需要固定大小的varchar(或字符串)输出时,我用整数列作为输入有类似的问题。例如,1到'01',12到'12'。这段代码工作:

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

如果输入也是varchar的列,则可以避免强制转换部分。

虽然这个问题是针对SQL Server 2008 R2的,但如果有人阅读的是2012或更高版本的SQL Server,从那以后,使用格式就容易多了。

您可以传递标准数字格式字符串自定义数字格式字符串作为格式参数(感谢瓦迪姆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

使用这个函数,它适合各种情况。

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

很简单

如:

DECLARE @DUENO BIGINT
SET @DUENO=5


SELECT 'ND'+STUFF('000000',6-LEN(RTRIM(@DueNo))+1,LEN(RTRIM(@DueNo)),RTRIM(@DueNo)) DUENO

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

我发现这个代码提供了一个解决方案。不确定它是否适用于所有版本的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的帖子是一样的。

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

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

用固定长度的方法试试。

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


select REPLICATE('0', 5 - LEN(123)) + '123'

我创建了这个函数,它满足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,' ')

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

所以我需要一个方法来处理负数和正数,如果需要,将它们格式化为两个字符,前导为零。无名氏们回答让我接近,但负时区值将出现为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'

最后我决定用这个:

RIGHT(STUFF(ReceiptNum, 1, 0, replicate('0',10)),10)