Convert number to varchar in SQL with formatting - sql

Is there a way in T-SQL to convert a TINYINT to VARCHAR with custom number formatting?
For instance, my TINYINT has a value of 3 and I want to convert it to a VARCH of 03, so that it always shows a 2 digit number.
I don't see this ability in the CONVERT function.

RIGHT('00' + CONVERT(VARCHAR, MyNumber), 2)
Be warned that this will cripple numbers > 99. You might want to factor in that possibility.

Use the RIGHT function...
e.g.
DECLARE #testnum TINYINT
SET #testnum = 3
PRINT RIGHT('00' + CONVERT(VARCHAR(2), #testnum), 2)

You can try this
DECLARE #Table TABLE(
Val INT
)
INSERT INTO #Table SELECT 3
INSERT INTO #Table SELECT 30
DECLARE #NumberPrefix INT
SET #NumberPrefix = 2
SELECT REPLICATE('0', #NumberPrefix - LEN(Val)) + CAST(Val AS VARCHAR(10))
FROM #Table

What is the value range? Is it 0 through 10? If so, then try:
SELECT REPLICATE('0',2-LEN(#t)) + CAST(#t AS VARCHAR)
That handles 0 through 9 as well as 10 through 99.
Now, tinyint can go up to the value of 255. If you want to handle > 99 through 255, then try this solution:
declare #t TINYINT
set #t =233
SELECT ISNULL(REPLICATE('0',2-LEN(#t)),'') + CAST(#t AS VARCHAR)
To understand the solution, the expression to the left of the + calculates the number of zeros to prefix to the string.
In case of the value 3, the length is 1. 2 - 1 is 1. REPLICATE Adds one zero.
In case of the value 10, the length is 2. 2 - 2 is 0. REPLICATE Adds nothing.
In the case of the value 100, the length is -1 which produces a NULL. However, the null value is handled and set to an empty string.
Now if you decide that because tinyint can contain up to 255 and you want your formatting as three characters, just change the 2-LEN to 3-LEN in the left expression and you're set.

declare #t tinyint
set #t =3
select right(replicate('0', 2) + cast(#t as varchar),2)
Ditto: on the cripping effect for numbers > 99
If you want to cater for 1-255 then you could use
select right(replicate('0', 2) + cast(#t as varchar),3)
But this would give you 001, 010, 100 etc

Here's an alternative following the last answer
declare #t tinyint,#v tinyint
set #t=23
set #v=232
Select replace(str(#t,4),' ','0'),replace(str(#t,5),' ','0')
This will work on any number and by varying the length of the str() function you can stipulate how many leading zeros you require. Provided of course that your string length is always >= maximum number of digits your number type can hold.

CorreciĆ³n: 3-LEN
declare #t TINYINT
set #t =233
SELECT ISNULL(REPLICATE('0',3-LEN(#t)),'') + CAST(#t AS VARCHAR)

Had the same problem with a zipcode field. Some folks sent me an excel file with zips, but they were formatted as #'s. Had to convert them to strings as well as prepend leading 0's to them if they were < 5 len ...
declare #int tinyint
set #int = 25
declare #len tinyint
set #len = 3
select right(replicate('0', #len) + cast(#int as varchar(255)), #len)
You just alter the #len to get what you want. As formatted, you'll get...
001
002
...
010
011
...
255
Ideally you'd "varchar(#len)", too, but that blows up the SQL compile. Have to toss an actual # into it instead of a var.

Related

SQL Server 2012 string functions

I have a field that can vary in length of the format CxxRyyy where x and y are numeric. I want to choose xx and yyy. For instance, if the field value is C1R12, then I want to get 1 and 12. if I use substring and charindex then I have to use a length, but I would like to use a position like
SUBSTRING(WPLocationNew, CHARINDEX('C',WPLocationNew,1)+1, CHARINDEX('R',WPLocationNew,1)-1)
or
SUBSTRING(WPLocationNew, CHARINDEX('C',WPLocationNew,1)+1, LEN(WPLocationNew) - CHARINDEX('R',WPLocationNew,1))
to get x, but I know that doesn't work. I feel like there is a fairly simple solution, but I am not coming up with it yet. Any suggestions
If these are cell references and will always be in the form C{1-5 digits}R{1-5 digits} you can do this:
DECLARE #t TABLE(Original varchar(32));
INSERT #t(Original) VALUES ('C14R4535'),('C1R12'),('C57R123');
;WITH src AS
(
SELECT Original, c = REPLACE(REPLACE(Original,'C',''),'R','.')
FROM #t
)
SELECT Original, C = PARSENAME(c,2), R = PARSENAME(c,1)
FROM src;
Output
Original
C
R
C14R4535
14
4535
C1R12
1
12
C57R123
57
123
Example db<>fiddle
If you need to protect against other formats, you can add
FROM #t WHERE Original LIKE 'C%[0-9]%R%[0-9]%'
AND PATINDEX('%[^C^R^0-9]%', Original) = 0
Updated db<>fiddle
It appears that you are attempting to parse an Excel cell reference. Those are predictably structured or I wouldn't suggest such an embarrassing hack as this.
Basically, take advantage of the fact that a try_cast in SQL ignores spaces when converting strings to numbers.
declare #val as varchar(20) = 'C1R12'
declare #newval as varchar(20)
declare #c as smallint
declare #r as smallint
--replace the C with 5 spaces
set #newval = replace(#val,'C',' ')
--replace the R with 5 spaces
set #newval = replace(#newval,'R',' ')
--take a look at the intermediate result, which is ' 1 14'
select #newval
set #c = try_cast(left(#newval,11) as smallint)
set #r = try_cast(right(#newval,6) as smallint)
--take a look at the results... two smallint, 1 and 14
select #c, #r
That can all be accomplished in one line for each element (a line for column and a line for row) but I wanted you to be able to understand what was happening so this example goes through the steps individually.
Here's yet another way:
declare #val as varchar(20) = 'C12R345'
declare #c as varchar(5)
declare #r as varchar(5)
set #c = SUBSTRING(#val, patindex('C%', #val)+1,(patindex('%R%', #val)-1)-patindex('C%', #val) )
set #r = SUBSTRING(#val, patindex('%R%', #val)+1, LEN(#val) -patindex('%R%', #val))
select cast(#c as int) as 'C', cast(#r as int) as 'R'
dbfiddle
There are lots of different ways to approach string parsing. Here's just one possible idea:
declare #s varchar(10) = 'C01R002';
select
rtrim( left(replace(stuff(#s, 1, 1, ''), 'R', ' '), 10)) as c,
ltrim(right(replace(substring(#s, 2, 10), 'R', ' '), 10)) as r
Strip out the 'C' and then replace the 'R' with enough spaces so that the left and right sides can be extracted using a fixed length and then easily trimmed back.
stuff() and substring() as used above are just different ways accomplish exactly the same thing. One advantage here is that it does use fairly portable string functions and it's conceivable that this is somewhat faster. This is also done inline and without multiple steps.

SqlServer - Concatenate an integer

I'm look for any help to concatenate an integer.
Example:
In a company a employee as a employee number.
And is number is 140024.
Now, the number 14 is the year (depending on the date), and it needs to be assigned automatically. The other number 0024 is my problem. I could get the number 24 but how can I add the 00 or 000 if the number is less than 10?
So I need help to concatenate all this. And also wanted to get it as an INT to make it as a primary key.
DECLARE #Your_Number INT = 24;
SELECT CAST(RIGHT(YEAR(GETDATE()), 2) AS NVARCHAR(2))
+ RIGHT('000000000' + CAST(#Your_Number AS NVARCHAR), 4) --<-- This 4
RESULT: 140024
The Number 4 Decides how many Total digits you want after the Year Digits.
you have two choice : working with varchar or int itself.
Example :
select cast(14 as char(2)) + right('0000' + cast(24 as varchar(4)),4)
or with int
select 14 * 10000 + 24
Where 10000 of course is the number you can have max. It could be 100, 1000 or more. But your number of digit is probably fixed so it should be fixed too.
try this..
CREATE FUNCTION [dbo].[fn_GetAutoGeneratedID]
(
#strPart VARCHAR(20),#strSeprator VARCHAR(5),#intPart VARCHAR(10)
)RETURNS VARCHAR(20)
AS
BEGIN
DECLARE #prefix VARCHAR(10)
SET #prefix=(SELECT CASE LEN(#intPart)
WHEN 1 THEN #strSeprator+'0000'+#intPart
WHEN 2 THEN #strSeprator+'000'+#intPart
WHEN 3 THEN #strSeprator+'00'+#intPart
WHEN 4 THEN #strSeprator+'0'+#intPart
ELSE #strSeprator+#intPart
END)
RETURN(SELECT #strPart+#prefix);
END
now call it as..
SELECT #MyNum=dbo.fn_GetAutoGeneratedID (#yourMonthPart,'',#YourNextpart )
Declare #i int=24
select replicate('0',4-len(cast(#i as varchar(10))))+cast(#i as
varchar(10))

Is there a simple way to do hexadecimal arithmetic using sql server/TSQL?

I have a column of hexadecimal values in a table. I want to add a hex value to all values in that table. If it were a simple int I would run something like this:
UPDATE myTable
SET num = num + 4000
Is there any way to do this simply using hexadecimal arithmetic? Or do I have to convert the column value to decimal, convert the value I want to add to decimal, add them, and convert the value back to hex? (And if so, what's the simplest way to do that?)
(NOTE: We are currently using sql server 2000.)
use something like :
print convert(varbinary(4),0 + 0x002E + 0x001D)
it should give you a result like :
0x0000004B
the zero in the equation fools it to believe its all numbers so it calculates the value.
Assuming that num is actually a string representation of the hexadecimal number, I think you can convert it to an integer by using a couple of User Defined Functions:
-- Based on Feodor's solution on
-- http://blog.sqlauthority.com/2010/02/01/sql-server-question-how-to-convert-hex-to-decimal/
CREATE FUNCTION fn_HexToInt(#str varchar(16))
RETURNS BIGINT AS BEGIN
SELECT #str=upper(#str)
DECLARE #i int, #len int, #char char(1), #output bigint
SELECT #len=len(#str),#i=#len, #output=case WHEN #len>0 THEN 0 END
WHILE (#i>0)
BEGIN
SELECT #char=substring(#str,#i,1)
, #output=#output
+(ASCII(#char)
-(case when #char between 'A' and 'F' then 55
else case when #char between '0' and '9' then 48 end
end))
*power(16.,#len-#i)
, #i=#i-1
END
RETURN #output
END
-- Example conversion back to hex string - not very tested
CREATE FUNCTION fn_IntToHex(#num int)
RETURNS VARCHAR(16) AS BEGIN
DECLARE #output varchar(16), #rem int
SELECT #output = '', #rem=0
WHILE (#num > 0)
BEGIN
SELECT #rem = #num % 16
SELECT #num = #num / 16
SELECT #output = char(#rem + case when #rem between 0 and 9 then 48 else 55 end) + #output
END
RETURN #output
END
select dbo.fn_HexToInt ('7FFF') -- = 32767
select dbo.fn_IntToHex(32767) -- = 7FFF
So you can try
UPDATE myTable
SET num = dbo.fn_IntToHex(dbo.fn_HexToInt(num) + 4000)
You can use the prefix 0x
eg
Select 0x3F + 2
returns 65
So
UPDATE myTable
SET num = num + 0x4000
(This works in SQL 2008 - I'm not sure if it's new since SQL 2000 - let me know!)
If you have two 0x values, they get concatenated by the + operator, so use convert to convert one of them to an int

Creating a Function in SQL Server with a Phone Number as a parameter and returns a Random Number

I am hoping someone can help me here as google is not being as forthcoming as I would have liked. I am relatively new to SQL Server and so this is the first function I have set myself to do.
The outline of the function is that it has a Phone number varchar(15) as a parameter, it checks that this number is a proper number, i.e. it is 8 digits long and contains only numbers. The main character I am trying to avoid is '+'. Good Number = 12345678 Bad Number = +12345678. Once the number is checked I would like to produce a random number for each phone number that is passed in.
I have looked at substrings, the like operator, Rand(), left(), Right() in order to search through the number and then produce a random number. I understand that Rand() will produce the same random number unless alterations are done to it but right now it is about actually getting some working code. Any hints on this would be great or even point me towards some more documentation. I have read books online and they haven't helped me, maybe I am not looking in the right places.
Here is a snippet of code I was working on the Rand
declare #Phone Varchar (15)
declare #Counter Varchar (1)
declare #NewNumber Varchar(15)
set #Phone = '12345678'
set #Counter = len(#Phone)
while #Counter > 0
begin
select case when #Phone like '%[0-9]%' then cast(rand()*100000000 as int) else 'Bad Number' end
set #counter = #counter - 1
end
return
Thanks for the help in advance
Emer
Simply use LIKE and ensure each digit is between 0 and 9.
One way to generate random numbers is CHECKSUM(NEWID()), or use this as the seed for RAND
IF #phone LIKE '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
SELECT #NewNumber = LEFT(
CAST(ABS(CHECKSUM(NEWID())) AS varchar(10)) +
CAST(ABS(CHECKSUM(NEWID())) AS varchar(10)) +
CAST(ABS(CHECKSUM(NEWID())) AS varchar(10)), 15)
Or the double negative LIKE with length check
IF #phone NOT LIKE '%[^0-9]%' AND LEN(#phone) = 8
SELECT #NewNumber = LEFT(
CAST(ABS(CHECKSUM(NEWID())) AS varchar(10)) +
CAST(ABS(CHECKSUM(NEWID())) AS varchar(10)) +
CAST(ABS(CHECKSUM(NEWID())) AS varchar(10)), 15)
I thought I would update my post with the solution I have come up with for other people who may be searching for something similar. From my research you are unable to use RAND() within a UDF. Instead you have to create a view and call it from that view.
Create Function [dbo].[AlterPhone](#Phone Varchar(15))
Returns varchar (15)
AS
BEGIN
declare #Counter int
declare #NewNumber varchar(15)
set #NewNumber = 0
select #NewNumber = case when len(#Phone)=8 and isnumeric(#Phone) = 1
then (select RandValue from dbo.vw_RandomVarchar) else 'Bad Number' end
return #NewNumber
END
/*
CREATE VIEW [dbo].[vw_RandomVarchar]
AS
SELECT cast(cast(rand()*100000000 as int)as varchar) AS RandValue
END
SELECT dbo.AlterPhone(12345678)
*/

Most efficient method for adding leading 0's to an int in sql

I need to return two fields from a database concatenated as 'field1-field2'. The second field is an int, but needs to be returned as a fixed length of 5 with leading 0's. The method i'm using is:
SELECT Field1 + '-' + RIGHT('0000' + CAST(Field2 AS varchar),5) FROM ...
Is there a more efficient way to do this?
That is pretty much the way: Adding Leading Zeros To Integer Values
So, to save following the link, the query looks like this, where #Numbers is the table and Num is the column:
SELECT RIGHT('000000000' + CONVERT(VARCHAR(8),Num), 8) FROM #Numbers
for negative or positive values
declare #v varchar(6)
select #v = -5
SELECT case when #v < 0
then '-' else '' end + RIGHT('00000' + replace(#v,'-',''), 5)
Another way (without CAST or CONVERT):
SELECT RIGHT(REPLACE(STR(#NUM),' ','0'),5)
If you can afford/want to have a function in your database you could use something like:
CREATE FUNCTION LEFTPAD
(#SourceString VARCHAR(MAX),
#FinalLength INT,
#PadChar CHAR(1))
RETURNS VARCHAR(MAX)
AS
BEGIN
RETURN
(SELECT Replicate(#PadChar, #FinalLength - Len(#SourceString)) + #SourceString)
END
I would do it like this.
SELECT RIGHT(REPLICATE('0', 5) + CAST(Field2 AS VARCHAR(5),5)
Not necessarily all that "Easier", or more efficient, but better to read. Could be optimized to remove the need for "RIGHT"
If you want to get a consistent number of total strings in the final result by adding different number of zeros, here is a little bit modification (for vsql)
SELECT
CONCAT(
REPEAT('0', 9-length(TO_CHAR(var1))),
CAST(var1 AS VARCHAR(9))
) as var1
You can replace 9 by any number for your need!
BRD