我有一个最多3个字符长的字符串,当它第一次创建在SQL Server 2008 R2。
我想用前导零填充它,所以如果它的原始值是“1”,那么新值将是“001”。或者如果它的原始值是“23”,那么新的值是“023”。或者如果它的原始值为124,则新值与原始值相同。
我使用的是SQL Server 2008 R2。如何使用T-SQL做到这一点?
我有一个最多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'
其他回答
使用这个函数,它适合各种情况。
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 @val varchar(5)
declare @maxSpaces int
set @maxSpaces = 3
set @val = '3'
select concat(REPLICATE('0',@maxSpaces-len(@val)),@val)
下面是一个更通用的左填充到任何所需宽度的技巧:
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有足够的长度来保存经过截断的转换结果。
对于那些想要更新现有数据的人,这里是查询:
update SomeEventTable set eventTime=RIGHT('00000'+ISNULL(eventTime, ''),5)
我创建了这个函数,它满足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,' ')