在SQL Server 2008 R2中首次创建时,我的字符串最长为3个字符。
我想用前导零填充它,因此,如果其原始值是“ 1”,那么新值将是“ 001”。或者,如果其原始值为'23',则新值为'023'。或者,如果其原始值为“ 124”,则新值与原始值相同。
我正在使用SQL Server 2008 R2。我将如何使用T-SQL做到这一点?
在SQL Server 2008 R2中首次创建时,我的字符串最长为3个字符。
我想用前导零填充它,因此,如果其原始值是“ 1”,那么新值将是“ 001”。或者,如果其原始值为'23',则新值为'023'。或者,如果其原始值为“ 124”,则新值与原始值相同。
我正在使用SQL Server 2008 R2。我将如何使用T-SQL做到这一点?
Answers:
如果该字段已经是字符串,则可以使用
SELECT RIGHT('000'+ISNULL(field,''),3)
如果您希望null显示为'000'
它可能是整数-那么您需要
SELECT RIGHT('000'+CAST(field AS VARCHAR(3)),3)
根据问题的要求,此答案仅在长度<= 3时有效,如果要更大,则需要将字符串常量和两个整数常量更改为所需的宽度。例如
'0000' and VARCHAR(4)),4
尽管问题是针对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
安全方法:
SELECT REPLACE(STR(n,3),' ','0')
这具有返回'***'
n <0或n> 999 的字符串的优点,这是输入越界的一个很好的明显指示。此处列出的其他方法将通过截断3个字符的子字符串的输入而无提示地失败。
SELECT REPLACE(STR('1',3),' ','0')
休息时间:SELECT REPLACE(STR('1A',3),' ','0')
。今天,当用户在输入字符串中输入字母而我无法测试这种情况时,这真让我很烦。
这是一种用于将左侧填充到任何所需宽度的更通用的技术:
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
足够长的长度,以保留截断后的转换结果。
使用适合各种情况的此功能。
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 @NumStr VARCHAR(250) = '2016'; SELECT REPLICATE('0', 12 - LEN(@NumStr)) + @NumStr;
它返回上述Salar的第一个示例。谢谢撒拉尔。
DECLARE @NumStr VARCHAR(250) = '2016'; SELECT REPLICATE('0', 10 - LEN(@NumStr)) + @NumStr;
返回0000002016
。
对于整数,可以使用从int到varchar的隐式转换:
SELECT RIGHT(1000 + field, 3)
之所以这样写是因为我对特定长度的要求最高(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
返回1234input
我专门来这里工作是为了解决如何将我的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'
我创建了此函数,该函数可满足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,' ')