How to convert integer to text aligning the text on the left? - sql-server

I need to convert
1
12
145
to (where I use S for SPACE)
SSSS1
SSS12
SS145
If I use CAST (VALUE as CHAR(5)) I get
1SSSS
12SSS
145SS
How to perform that?

SELECT STR(N,5)
FROM (VALUES (1),(12),(145)) T(N)
Returns
-----
1
12
145

RIGHT(' ' + CAST (VALUE as VARCHAR(5)), 5)
More generally:
DECLARE #PadTo tinyint;
SET #PadTo = 5;
SELECT
RIGHT(REPLICATE(' ', #PadTo) + CAST(VALUE as VARCHAR(255)), #PadTo)
...

You can find your ansewer here:
SQL Padding
particularly:
SELECT RIGHT ('000000'+ CAST (#Number AS varchar), 6)

declare #T table(Value int)
insert into #T values (1),(12),(145)
select right(stuff(Value, 1, 0, space(5)), 5)
from #T

Related

How to insert a character into a string every 3 characters from the right

I have a string made up of numbers. The length of the string ranges anywhere from 1 character to 9 characters.
I want to insert a dash (-) every three characters from the right. This will only be relevant for strings with upwards of three characters.
This will just be a select statement, as I do not want to actually update the string itself.
For example,
8 should return 8
476 should return 476
4767 should return 4-767
45907392 should return 45-907-392
845907392 should return 845-907-392
This should work:
select
*,
replace(format(n,'#,#'),',','-')
from (values (8),(476),(4767),(45907392),(845907392)) x (n)
Change , to . if it's thousand separator in your system, or provide a culture as third parameter in FORMAT function so it always works the same.
Since SQL Server 2012 you can use the FORMAT function as described in the other answers. In case you want to format a string value like 'abcde' too you can use only string functions like this:
DECLARE #str VARCHAR(100) = '845907392';
-- 845-907-392
SELECT REVERSE(SUBSTRING(REVERSE(#str), 7, 3))
+ CASE WHEN LEN(#str)>6 THEN '-' ELSE '' END
+ REVERSE(SUBSTRING(REVERSE(#str), 4, 3))
+ CASE WHEN LEN(#str)>3 THEN '-' ELSE '' END
+ REVERSE(SUBSTRING(REVERSE(#str), 1, 3))
You can also create a function:
CREATE FUNCTION dbo.GetFormatTripleDash (#str varchar(255))
RETURNS VARCHAR(255)
AS
BEGIN
DECLARE #retStr VARCHAR(255) = REVERSE(SUBSTRING(REVERSE(#str), 7, 3))
+ CASE WHEN LEN(#str)>6 THEN '-' ELSE '' END
+ REVERSE(SUBSTRING(REVERSE(#str), 4, 3))
+ CASE WHEN LEN(#str)>3 THEN '-' ELSE '' END
+ REVERSE(SUBSTRING(REVERSE(#str), 1, 3))
RETURN(#retStr)
END
You can use this funtion like this:
-- 845-907-392
SELECT dbo.GetFormatTripleDash('845907392')
A more flexible solution using the function. Now you can use a much longer string value and you can define the part size separated by - character.
CREATE FUNCTION dbo.GetFormatDash (#str varchar(255), #partSize INT = 3)
RETURNS VARCHAR(255)
AS
BEGIN
DECLARE #startSize INT = 0;
DECLARE #retStr VARCHAR(255) = '';
WHILE #startSize < LEN(#str)
BEGIN
SET #retStr = REVERSE(SUBSTRING(REVERSE(#str), #startSize + 1, #partSize)) + CASE WHEN #startSize > 0 THEN '-' ELSE '' END + #retStr;
SET #startSize = #startSize + #partSize;
END
RETURN(#retStr)
END
You can use this improved function like this:
-- 12-345-678-901-234-567-890
SELECT dbo.GetFormatDash('12345678901234567890', DEFAULT)
SELECT dbo.GetFormatDash('12345678901234567890', 3)
-- 12345-67890-12345-67890
SELECT dbo.GetFormatDash('12345678901234567890', 5)
demo on dbfiddle.uk
Its a bit gross but it works! Try i
t and let me know if you agree
SELECT
CASE
WHEN LEN(yourColumn)>6 THEN format(CAST(YourColumn AS NUMERIC), '###-###-###')
WHEN LEN(YourColumn)>3 THEN format(CAST(YourColumn AS NUMERIC), '###-###')
ELSE YourColumn
END
Here is another way to do it, albeit more typing
SELECT
CASE
WHEN LEN(yourColumn)>6 THEN SUBSTRING(YourColumn, 1, 3) +'-'+ SUBSTRING(YourColumn, 4, 3)
WHEN LEN(YourColumn)>3 THEN REVERSE(SUBSTRING(REVERSE(YourColumn), 1, 3) +'-'+ SUBSTRING(REVERSE(YourColumn), 4, 3))
ELSE YourColumn
END
Try this. I'm sure it can also be extended to allow for any number of characters with a bit of effort
declare #input nvarchar(100) = '845907392'
declare #separator char(1) = '-'
--option1 - CTE
;with dash1 as (
select isnull(stuff(reverse(#input), 1+3, 0, #separator), reverse(#input)) as v
)
, dash2 as(
select isnull(stuff(v, 1+7, 0, #separator), v) as v from dash1
)
select reverse(v) from dash2
--option2 - Non CTE
select reverse(isnull(stuff(isnull(stuff(reverse(#input), 1+3, 0, #separator), reverse(#input)), 1+7, 0, #separator), isnull(stuff(reverse(#input), 1+3, 0, #separator), reverse(#input))))
Try this using format() function.
Select Replace(format(8, '#,##0'), ',', '-')
Select Replace(format(476, '#,##0'), ',', '-')
Select Replace(format(45907392, '#,##0'), ',', '-')
Select Replace(format(845907392, '#,##0'), ',', '-')
Live db<>fiddle demo.
A solution with a recursive CTE:
with cte as (
select col, len(col) - 3 pos from tablename
union all
select
cast(left(col, pos) + '-' + right(col, len(col) - pos) as varchar(100)),
pos - 3
from cte
where pos > 0
)
select col from cte
where pos <= 0
See the demo.
Results:
> | col |
> | :---------- |
> | 8 |
> | 476 |
> | 845-907-392 |
> | 45-907-392 |
> | 4-767 |

Find MaxNonZeroPosition of a scale in a decimal

I have a scenario, wherein I need a sql query to find out the MaxNonZeroPosition in a scale of every decimal column of a database using SQL Server.
For ex: 43321.70090100, Max nonZero Position is 6 here.
In order to reduce complexity I've put part in a subquery. This should give you what you need:
DECLARE #T DECIMAL(20, 12) = 43321.70090100
SELECT LEN(CONVERT(VARCHAR(20), SS)) - PATINDEX('%[^0]%', REVERSE(SS))
FROM (
SELECT #T Ori
, SUBSTRING(CONVERT(VARCHAR(20), #T), CHARINDEX('.', #T), LEN(#T)) SS
) Sub
Another approach
declare #test decimal(20, 12) = 221123.812000430035000
select len(replace(#test, 0, ' ')) - charindex('.', #test)

SQL Server : select all after specific character

How I can select
"ALT1" if value is "W61N03D20V0-WHIH-ALT1"
"ALT2" if for "W61N03D20V0-WHIH-ALT2"
"SW" for "W61N03D20V0-WHIH-SW"
"Default" for "W61N26D1YA1-VICU" (without prefix)
"Defailt" for "W61N27D21V2-AZTD"
In other words I'm looking for a way extract last part after second suffix, but if I have't second suffix - then default
Thanks for advice
Try it like this:
First you "split" the string on its minus signs with the XML trick.
Then you read the third node from you XML - voila!
CREATE TABLE #tbl(content VARCHAR(100));
INSERT INTO #tbl VALUES('W61N03D20V0-WHIH-ALT1')
,('W61N03D20V0-WHIH-SW')
,('W61N26D1YA1-VICU');
WITH SplittedAsXml AS
(
SELECT CAST('<x>' + REPLACE(content,'-','</x><x>') + '</x>' AS XML) AS Content
FROM #tbl
)
SELECT ISNULL(Content.value('/x[3]','varchar(max)'),'default') AS TheThirdPart
FROM SplittedAsXml;
DROP TABLE #tbl;
The result
ALT1
SW
default
Going this ways would also give you the chance to get the other parts in one go just querying /x[1] and /x[2] too
I did it using the built-in substring() function:
declare #str VARCHAR(40) = 'W61N03D20V0-WHIH-ALT1' -- also works for the other examples
declare #sep VARCHAR(1) = '-'
declare #middleToEnd VARCHAR(40) = substring(#str, charindex(#sep, #str) + 1, len(#str))
declare #pos INT = charindex(#sep, #middleToEnd)
declare #lastPart VARCHAR(40) =
CASE WHEN #pos = 0
THEN 'Default'
ELSE substring(#middleToEnd, #pos + 1, len(#middleToEnd))
END
select #lastPart
For best performance, you can solve it with this one-liner(calculation is one line)
SELECT
COALESCE(STUFF(col,1,NULLIF(CHARINDEX('-',col, CHARINDEX('-',col)+1), 0),''),'Default')
FROM (values
('W61N03D20V0-WHIH-ALT1'),('W61N03D20V0-WHIH-ALT2'),
('W61N03D20V0-WHIH-SW'),('W61N26D1YA1-VICU'),
('W61N27D21V2-AZTD')) x(col)
Result:
ALT1
ALT2
SW
Default
Default
If I understand what you are asking for, the following does what you need:
-- fake table
WITH SomeTable AS (
SELECT 'W61N03D20V0-WHIH-ALT1' AS Field1
UNION ALL
SELECT 'W61N03D20V0-WHIH-SW'
UNION ALL
SELECT 'W61N26D1YA1-VICU'
)
-- select
SELECT
CASE CHARINDEX('-WHIH-', Field1)
WHEN 0 THEN 'Default'
ELSE SUBSTRING(Field1, CHARINDEX('-WHIH-', Field1) + 6, LEN(Field1) - (CHARINDEX('-WHIH-', Field1) + 5))
END
FROM SomeTable
Use can use a CASE expression to check whether the string starts with W61N03D20V0-WHIH.
If it starts with it use a combination of RIGHT, REVERSE and CHARINDEX functions to get last part from the string, else Default.
Query
select case when [your_column_name] like 'W61N03D20V0-WHIH%'
then right([your_column_name], charindex('-', reverse([your_column_name]), 1) - 1)
else 'Default' end as new_column_name
from your_table_name;
SQl Fiddle demo

SQL server convert hex string to varbinary

I have a string column that represents hex values, for example -
'274', '1A7', '3D1' and so on.
Now I need to convert these values to their integer values, so that '10' will be converted to 16, for example.
The code I use:
SELECT CONVERT(int, CONVERT(varbinary, '0x' + case when replicate('0', len(myHex) / 2) + myHex = '0' then '00' else replicate('0', len(myHex) / 2) + myHex end, 1))
I'm actually padding the string with a zero or two to make it's length even, and adding the '0x' prefix. However some (random) rows fail.
Is there another way to convert the values?
Thanks.
please give feedback
so that i can improve my answer
Here is one way to do it:
//create function fn_HexToIntnt(#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
or
SELECT CONVERT(INT, 0×00000100)
SELECT CONVERT(VARBINARY(8), 256)

Convert Hexadecimal to INT and vice versa

I will be creating a sequential Serial Number made from Hexadecimal values
With this Format:
XX-XX-XX-YYYY
Which XX-XX-XX is default value
And YYYY is the incrementing hexa decimal value
Now to create the serial number based on hex value I need Add 6 to the last generated hex value
MIN: 2D41 + 6 = 2D47
2D47 + 6 ... and so on
MAX: 4100 generation of serial will stop when I meet the MAX value.
I already created it in c# but I need to do it on SQL
int num1 = int.Parse("2D41", NumberStyles.HexNumber); //Convert hex to int
int result = num1 + 6; //Add + 6 for increment
string myHex = result.ToString("X"); //Convert result to hex
MessageBox.Show(myHex); // result 2D47
How can this be done in T-SQL?
DECLARE #x VARBINARY(8) = 0x00002D41;
SELECT CONVERT(VARBINARY(8), CONVERT(INT, #x) + 6);
In order to handle the output as a string:
DECLARE #x VARBINARY(8) = 0x00002D41;
SELECT CONVERT(CHAR(10), CONVERT(VARBINARY(8), CONVERT(INT, #x) + 6), 1);
Hope this helps you
declare #seed varchar(max) = '2D41';
declare #limit varchar(max) = '4100';
select convert(int, convert(varbinary(max), '0x'+#seed,1)),
convert(int, convert(varbinary(max), '0x'+#limit,1));
;with seedlimit(seed, limit) as (
select convert(int, convert(varbinary(max), '0x'+#seed,1)),
convert(int, convert(varbinary(max), '0x'+#limit,1))
)
select SerialNumber = 'XX-XX-XX-' + right(convert(varchar(10),cast(s.seed + 6 * v.number as varbinary(max)),1),4)
from seedlimit s
join master.dbo.spt_values v on type='p'
where s.seed + 6 * v.number <= s.limit;
The basic ingredients are in there for you to create a view/procedure/function out of the answer,
Output:
SerialNumber
-------------
XX-XX-XX-2D41
XX-XX-XX-2D47
...
XX-XX-XX-40F7
XX-XX-XX-40FD
If you already have it in C#, leave it there and simply convert your code to a SQL CLR function.
For a simple example see:
http://blog.sqlauthority.com/2008/10/19/sql-server-introduction-to-clr-simple-example-of-clr-stored-procedure/

Resources