Reputation: 21396
I have a string that is up to 3 characters long when it's first created in SQL Server 2008 R2.
I would like to pad it with leading zeros, so if its original value was '1' then the new value would be '001'. Or if its original value was '23' the new value is '023'. Or if its original value is '124' then new value is the same as original value.
I am using SQL Server 2008 R2. How would I do this using T-SQL?
Upvotes: 584
Views: 1340825
Reputation: 1
lots of helpful stuff in here - leaving this as an artifact for others who find this article in a google search like me - I was trying to figure this out today with Zip Codes which was a mess because we wanted what should be the left 5 but some leading 0's were trimmed so some were 3 digits that needed two leading 0's padded and some were 7 digits that needed two padded, so I ended up going with a case statement - not super elegant but efficient and got the job done.
UPDATE q
SET q.Zip =
CASE WHEN LEN(q.Zip) IN (4,8) THEN '0'+ LEFT(q.Zip,4)
WHEN LEN(q.Zip) IN (3,7) THEN '00'+ LEFT(q.Zip,3)
WHEN LEN(q.Zip) IN (2,6) THEN '000'+ LEFT(q.Zip,2)
WHEN LEN(q.Zip) = 1 THEN '0000'+ LEFT(q.Zip,1)
ELSE LEFT(q.Zip,5)
END
FROM #BadData q
Upvotes: 0
Reputation: 1
SELECT CASE WHEN LEN(yourintegerfield) >5 THEN convert( varchar,yourintegerfield) else REPLICATE('0',5 - LEN(yourintegerfield)) + convert( varchar,yourintegerfield) end from yourtable
This has the advantage of not returning NULL when the actual number is longer than the desired length, useful for formatting barcodes from identity columns
Upvotes: 0
Reputation: 74187
Here's a more general technique for left-padding to any desired width:
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)
However, if you're dealing with negative values, and padding with leading zeroes, neither this, nor other suggested technique will work. You'll get something that looks like this:
00-123
[Probably not what you wanted]
So … you'll have to jump through some additional hoops Here's one approach that will properly format negative numbers:
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
)
One should note that the convert()
calls should specify an [n]varchar
of sufficient length to hold the converted result with truncation.
Upvotes: 36
Reputation: 41
Finally I decide to use this:
RIGHT(STUFF(ReceiptNum, 1, 0, replicate('0',10)),10)
Upvotes: 2
Reputation: 75
I know this is an old ticket but I just thought I'd share this:
I found this code which provides a solution. Not sure if it works on all versions of MSSQL; I have MSSQL 2016.
declare @value as nvarchar(50) = 23
select REPLACE(STR(CAST(@value AS INT) + 1,4), SPACE(1), '0') as Leadingzero
This returns "0023".
The 4 in the STR function is the total length, including the value. For example, 4, 23 and 123 will all have 4 in STR and the correct amount of zeros will be added. You can increase or decrease it. No need to get the length on the 23.
Edit: I see it's the same as the post by @Anon.
Upvotes: 5
Reputation: 3267
I came here specifically to work out how I could convert my timezoneoffset to a timezone string for converting dates to DATETIMEOFFSET in SQL Server 2008. Gross, but necessary.
So I need 1 method that will cope with negative and positive numbers, formatting them to two characters with a leading zero if needed. Anons answer got me close, but negative timezone values would come out as 0-5
rather than the required -05
So with a bit of a tweak on his answer, this works for all timezone hour conversions
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'
Upvotes: 0
Reputation: 9
I created this function which caters for bigint and one leading zero or other single character (max 20 chars returned) and allows for length of results less than length of input number:
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,' ')
Upvotes: -1
Reputation: 116
Try this with fixed length.
select right('000000'+'123',5)
select REPLICATE('0', 5 - LEN(123)) + '123'
Upvotes: 7
Reputation: 51
For a more dynamic approach try this.
declare @val varchar(5)
declare @maxSpaces int
set @maxSpaces = 3
set @val = '3'
select concat(REPLICATE('0',@maxSpaces-len(@val)),@val)
Upvotes: 3
Reputation: 70513
If the field is already a string, this will work
SELECT RIGHT('000'+ISNULL(field,''),3)
If you want nulls to show as '000'
It might be an integer -- then you would want
SELECT RIGHT('000'+CAST(field AS VARCHAR(3)),3)
As required by the question this answer only works if the length <= 3, if you want something larger you need to change the string constant and the two integer constants to the width needed. eg
'0000' and VARCHAR(4)),4
Upvotes: 931
Reputation: 2762
Although the question was for SQL Server 2008 R2, in case someone is reading this with version 2012 and above, since then it became much easier by the use of FORMAT.
You can either pass a standard numeric format string or a custom numeric format string as the format argument (thank Vadim Ovchinnikov for this hint).
For this question for example a code like
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#');
outputs
001
001
Upvotes: 234
Reputation: 11
Simple is that
Like:
DECLARE @DUENO BIGINT
SET @DUENO=5
SELECT 'ND'+STUFF('000000',6-LEN(RTRIM(@DueNo))+1,LEN(RTRIM(@DueNo)),RTRIM(@DueNo)) DUENO
Upvotes: 1
Reputation: 2114
Use this function which suits every situation.
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
Sample output
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
Upvotes: 19
Reputation: 321
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.
Upvotes: 2
Reputation: 378
Wrote this because I had requirements for up to a specific length (9). Pads the left with the @pattern ONLY when the input needs padding. Should always return length defined in @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
Returns 1234input
Upvotes: 1
Reputation: 10908
The safe method:
SELECT REPLACE(STR(n,3),' ','0')
This has the advantage of returning the string '***'
for n < 0 or n > 999, which is a nice and obvious indicator of out-of-bounds input. The other methods listed here will fail silently by truncating the input to a 3-character substring.
Upvotes: 182
Reputation: 5657
Here is a variant of Hogan's answer which I use in SQL Server Express 2012:
SELECT RIGHT(CONCAT('000', field), 3)
Instead of worrying if the field is a string or not, I just CONCAT
it, since it'll output a string anyway. Additionally if the field can be a NULL
, using ISNULL
might be required to avoid function getting NULL
results.
SELECT RIGHT(CONCAT('000', ISNULL(field,'')), 3)
Upvotes: 53
Reputation: 291
I have always found the following method to be very helpful.
REPLICATE('0', 5 - LEN(Job.Number)) + CAST(Job.Number AS varchar) as 'NumberFull'
Upvotes: 29
Reputation: 5616
For those wanting to update their existing data here is the query:
update SomeEventTable set eventTime=RIGHT('00000'+ISNULL(eventTime, ''),5)
Upvotes: 6
Reputation: 3450
For integers you can use implicit conversion from int to varchar:
SELECT RIGHT(1000 + field, 3)
Upvotes: 4