SqlServer - Concatenate an integer - sql

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))

Related

Insert zero between two IDs and make it length 10 in Stored Procedure

I am new to Stored Procedures, I am using MSSMS
So what I want is I have a table aItemPackingDetail and I have an sp to insert values into the table
ALTER PROCEDURE [dbo].[spInsertaItemPackingDetail]
#ItemID INT
,#PackingTypeID INT
,#PackingSlNo INT
,#PackingBarCode VARCHAR(25)
,#active BIT
AS
BEGIN
INSERT INTO aItemPackingDetail (
ItemID
,PackingTypeID
,PackingSlNo
,PackingBarCode
,active
)
VALUES (
#ItemID
,#PackingTypeID
,#PackingSlNo
,#PackingBarCode
,#active
)
END
As you can see this is a simple sp for insert. Then I got an update to do. If #PackingBarCode is null or empty I need to create a barcode in sp and save it.
The format of barcode needs to be like
#ItemID+ Zeros +#PackingTypeID // length needs to be 10
ie. if
#ItemID = 1212 and #PackingTypeID = 4521 then #PackingBarCode
needs to be#PackingBarCode
= 1212004521` so on.
And if length of #ItemID+#PackingTypeID >= 10 then dont add any zeros.
This as far as I did, I am stuck and no idea how to complete please help.
ALTER PROCEDURE [dbo].[spInsertaItemPackingDetail]
#ItemID INT
,#PackingTypeID INT
,#PackingSlNo INT
,#PackingBarCode VARCHAR(25)
,#active BIT
AS
BEGIN
-- declare variables to store ount ant zeros
DECLARE #ItemIDcount AS INT
DECLARE #PackingTypeIDCount AS INT
DECLARE #noofZeros AS INT
DECLARE #Barcode AS INT
-- find count of ids
SET #ItemIDcount = LEN(#ItemID)
SET #PackingTypeIDCount = LEN(#PackingBarCode)
-- how many zeros needed
IF (#ItemIDcount + #PackingTypeIDCount) < 10
BEGIN
SET #noofZeros = 10 - (#ItemIDcount + #PackingTypeIDCount)
END
-- if #PackingBarCode becomes null or empty
IF #PackingBarCode = NULL OR #PackingBarCode = ''
BEGIN
SET #PackingBarCode = -- how to create barcode??
END
INSERT INTO aItemPackingDetail (
ItemID
,PackingTypeID
,PackingSlNo
,PackingBarCode
,active
)
VALUES (
#ItemID
,#PackingTypeID
,#PackingSlNo
,#PackingBarCode
,#active
)
END
You can do it like this:
DECLARE #ItemID INT = 1212
, #PackingTypeID INT = 4521
SELECT CASE
WHEN LEN(#ItemID) + LEN(#PackingTypeID) < 10
THEN CONCAT(#ItemID, RIGHT(CONCAT('0000000000', #PackingTypeID), 10 - LEN(#ItemID)))
ELSE CONCAT(#ItemID, #PackingTypeID)
END AS BarCode
Result: 1212004521
The idea is basically to stick 10 0's in front of #PackingTypeID, and only taking those you need.
Here is a simple solution:
DECLARE
#ItemID INT = 1212,
#PackingTypeID INT = 4521
SELECT CAST(#ItemID AS VARCHAR)
+ REPLICATE('0', 10 - (LEN(CAST(#ItemID AS VARCHAR)) + LEN(CAST(#ItemID AS VARCHAR))))
+ CAST(#PackingTypeID AS VARCHAR)
Another approach (apart from concatenating strings) is to solve the problem mathematically, using base 10 logarithms to find the number of digits in each number.
Essentially, you want to multiply the first number by 10 until the number is 10 digits long, and then add the second number. The padding zeroes will automatically be where you want them to be. The only case to cover separately is when the total length is already 10 or greater.
BEGIN
DECLARE
#ItemID BIGINT = 1212,
#PackingTypeID BIGINT = 4521
SELECT
CASE
WHEN FLOOR(LOG10(#ItemID))+FLOOR(LOG10(#PackingTypeID)) >= 8
THEN CONVERT(varchar, #ItemID * POWER(10,FLOOR(LOG10(CAST(#PackingTypeID AS FLOAT)))+1) + #PackingTypeID)
ELSE
CONVERT(varchar, #ItemID * POWER(10,9-FLOOR(LOG10(CAST(#ItemID AS FLOAT)))) + #PackingTypeID)
END
END;
GO
EDIT
Note that the above will preserve the two numbers, regardless of their length, as per the following:
#ItemID = 12345
#PackingTypeID = 67891
--> 1234567891
#ItemID = 12345
#PackingTypeID = 678912
--> 12345678912
#ItemID = 1234
#PackingTypeID = 6789
--> 1234006789
If you want either of the numbers truncated (see case 2 above), to arrive at a maximum of 10 digits, then you probably need some more logic added. However, if the sum of the digits will never be greater than 10 (before the zeroes are added), then this is a moot point.

Select Part of Column

I was wondering if anyone could help with a query to select part of a column.
The column 'criteriadata' contains data that would look like this:
CriteriaData
14 27 15 C
14 30 15 DD
14 38 15 Pass
14 33 15 Pass
How can I select just the data that appears after the number 15.
Many thanks.
SELECT RIGHT(CriteriaData,
LEN(CriteriaData) - CHARINDEX('15', CriteriaData, 1) - 2)
FROM TableName
WHERE CriteriaData LIKE '%15%';
SQL Fiddle Demo
declare #T table
(
CriteriaData varchar(20)
)
insert into #T values
('14 27 15 C'),
('14 30 15 DD'),
('14 38 15 Pass'),
('14 33 15 Pass')
select stuff(CriteriaData, 1, 3+charindex(' 15 ', CriteriaData), '')
from #T
Result:
---------
C
DD
Pass
Pass
If CriteriaCData always contains a pattern of 3 numbers of 2 numerics separated by a space then you always want to retrieve from 10th chars:
select SUBSTR(CriteriaCData, 10) from xxx
If you are under oracle min 10.g then use REGEXP_SUBSTR to retrieve the alpha pattern
SELECT upper(REGEXP_SUBSTR(CriteriaCData, '[a-zA-Z]*$')) FROM xxx
Since you seem to want everything from the ninth character onwards, you could use RIGHT and LEN
SELECT right([CriteriaData], len([CriteriaData]) - 9)
However, you'd be better off normalizing your data so it was already in a seperate column.
On oracle use LENGTH instead of LEN
SELECT substr(CriteriaData, 8, LENGTH(CriteriaData) - 9) from table
You should use substring with left functions
Have a look at this: How to extract this specific substring in SQL Server?
And this: http://msdn.microsoft.com/en-us/library/aa259342(v=sql.80).aspx
SELECT substring(criteriadata, 9, LEN(criteriadata)-8) from table
This assumes that the position of 15 is fixed.
Declare #x nvarchar(100) = '14 30 15 DD';
Select substring(#x, (select charindex('15',#x,1) + 2) ,len(#x));
I created a SQL function to split the criteria by the spaces and used the last remaining value after the last space.
create function dbo.getCriteria
(
#criteria varchar(500)
)
returns varchar(500)
begin
declare #space as int
select #space=charindex(' ', data) from mydata
while #space > 0
begin
set #criteria=substring(#criteria, #space + 1, len(#criteria))
select #space=charindex(' ', #criteria)
end
return #criteria
end
select dbo.getCriteria(data) from mydata
SELECT
RIGHT(CriteriaData, LEN(CriteriaData) - (CHARINDEX('15', CriteriaData, 1) - 2))
FROM
MyTable;
As I had trouble making prior answers work, I had to find my own and figure for future reference I'd leave it on Stack Overflow. My field has XML but it's an NVarchar field and should generalise just fine - if you have a clear criteria for left AND right surrounding strings.
It's not a complete match to this question but I hope it helps someone else who has huge strings in their columns and needs to snip out a string that varies in between two others!
WITH r
AS (
SELECT TOP 100 RIGHT(XMLData, LEN(XMLData)-CHARINDEX('<INVOICE_NO>', XMLData)-11) AS xmldata
FROM IncomingPartsInvoiceXML)
SELECT LEFT(xmldata, CHARINDEX('<\/INVOICE_NO>', XMLData)-1)
FROM r;

Modify int result of count in sql server 2005

I am working on sql server 2005 and I am taking count from a specific table
SELECT count(StudentIdReference) as studentCount FROM StudentTable
Right now this select statement is returning me result like 2 or 78 or 790. But in future it will grow rapidly and on UI I don't have sufficient space to show the digit like 1000000.
What I want that after 3 digit, I will get the number like 1K or 1.6K, just as we see on stackoverflow.
This would be simpler to be done in the Presentation Layer of your application.
You coud write a user function and do something like this....
CREATE FUNCTION prettyPrint
(#number int)
RETURNS varchar(30)
AS
BEGIN
declare #return varchar(30)
set #return = cast(#number as varchar(3))
if #number > 1000
set #return = ''+ cast((#number/1000) as varchar(3)) + '.' + cast((#number % 1000)/100 as varchar(3)) +'K'
-- here must be more 'exceptions' or change all this about the magic number 1000
return #return
end
select dbo.prettyPrint(1500)
SELECT prettyPrint(count(StudentIdReference)) as studentCount FROM StudentTable
As others have stated you should really be doing this in your Presentation Layer not at the DB, however, this will do it for you:
Declare #StudentCount int,
#StudentCountFormatted varchar(10)
Select #StudentCount = Count(StudentIdReference) as studentCount FROM StudentTable
If #StudentCount > 999
Begin
Select #StudentCountFormatted = Convert(Varchar(10), Convert(numeric(19,1), (#StudentCount/ 1000.00))) + 'K'
End
Else
Begin
Select #StudentCountFormatted = #StudentCount
End
Select #StudentCountFormatted
You need to write your own logic to show such text. There is no built-in method.
I would return the COUNT as-is from SQL Server and leave the formatting up to the UI. This is because:
1) usually easier/performant to do formatting/string manipulation outside of SQL
2) different places in your code using the same query may want to use the data in different ways (maybe not now, but could do in future) so returning the count as-is gives you that flexibility - i.e. won't need 1 version to return the count as an INT and another to return the same as a formatted VARCHAR
You could do it in SQL, but in general I believe in pushing this in to the UI as it's a display/formatting behaviour.
You can always try something like this
SELECT
CASE
WHEN len(cast(count(*) as varchar(10)))< 4 then cast(count(*) as varchar(10))
WHEN len(cast(count(*) as varchar(10)))> 4 and len(cast(count(*)as varchar(10)))< 7
THEN cast(cast(count(*) / 1000.0 as decimal(10,1)) as varchar(10)) + 'k'
ELSE cast(cast(count(*) / 1000000.0 as decimal(10,1)) as varchar(10)) + 'm'
END StudentCount
FROM StudentTable

Convert number to varchar in SQL with formatting

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.

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