Function that creates unique reference no with sql server 2008 - tsql

I have an asp.net application that uses SQL Server 2005. In this application I want to create a function that returns unique reference numbers for new Inquiry Id.
I read about UNIQUEIDENTIFIER but it has a specific format like 1548C3E02-2D73-4244-8787-D45AC590519A.
I want output like 1703-HJIF-2012. Here first have combination of current datepart like date and month, second is random string which auto generate and third one is year part of current date. I don't have any idea how I could create such a function and how I would be calling this function from a stored procedure and get result string from function with this required format.
here some one posted me this function but this generates spaces instead of 0 :
create function UniqueRefNum (#r1 float, #r2 float, #r3 float, #r4 float)
returns char(14)
begin
-- Not sure if rand() might return 1.0
-- If it does, the conversion code below would produce a character that's not an
-- uppercase letter so let's avoid it just in case
if #r1 = 1.0 set #r1 = 0
if #r2 = 1.0 set #r2 = 0
if #r3 = 1.0 set #r3 = 0
if #r4 = 1.0 set #r4 = 0
declare #now datetime
set #now = getdate() -- or getutcdate()
declare #m char(2)
if month(#now) < 10
set #m = '0' + month(#now)
else
set #m = month(#now)
declare #d char(2)
if day(#now) < 10
set #d = '0' + day(#now)
else
set #d = day(#now)
return #m + #d + '-' +
char(65 + cast(#r1 * 26 as int)) +
char(65 + cast(#r2 * 26 as int)) +
char(65 + cast(#r3 * 26 as int)) +
char(65 + cast(#r4 * 26 as int)) +
'-' + cast(year(#now) as varchar)
end
You then call the function from your stored procedure like this:
declare #uniqueRef char(14)
set #uniqueRef = dbo.UniqueRefNum(rand(), rand(), rand(), rand())
---------------Updated-----------------------------
it's generates out put is like that :
4 24-HHBH-2014
and i want output something like this :
2404-HHBH-2014
DDMM-XXXX-YYYY

You need to cast the day/month values to char before concatenating the strings.
declare #m char(2)
if month(#now) < 10
set #m = '0' + cast(month(#now) as char(1))
else
set #m = month(#now)
declare #d char(2)
if day(#now) < 10
set #d = '0' + cast(day(#now) as char(1))
else
set #d = day(#now)
The thing is that the string in '0' + month(#now) is converted to integer and then the two numbers are added up.

Related

Coverting/ Casting operators to integer

I want to convert/ cast these operators ( '/' and '*') if this is possible. Maybe you know how that works or you know what the internal coding of division and multiplication is?! Maybe then I can continue with that?
What I want to do is, based on the last number of the current system time, I want to decide if that number is odd or even, and then do a multiplication or division in the next calculations.
CREATE FUNCTION CalculateFactor()
RETURNS NVARCHAR(50)
AS
BEGIN
DECLARE #time DATETIME2(7)
DECLARE #length INT
DECLARE #value NVARCHAR(20)
DECLARE #operator NVARCHAR(20)
SET #time = SYSDATETIME()
SELECT #length = LEN(#time)
SELECT #value = RIGHT(#time, 1);
IF (#value % 2 = 0)
SET #operator = '*'
ELSE SET #operator = '/'
DECLARE #SQL NVARCHAR(20)
SET #SQL = '10' + #operator + '2' --I get only 10 / 2 and 10 * 2 because that are strings and that is why I cannot get a result of the operation, but I want 5 and 20
RETURN #SQL
END
GO

Assigning a value from a looped column name variable in a SELECT statement

I'm having a hard time trying to assign a field name and then place that into a SELECT statement in T SQL. First - I want to get the SELECT statement to work without the convert error popping up, then I want the field value to be assigned to another variable. My code that fails is below.
DECLARE #lid integer
DECLARE #lrid integer
DECLARE #pct integer
DECLARE #rds integer
SET #lid = 4
SET #lrid = 46
SET #pct = 75
SET #rds = 4
DECLARE #c integer --SIMPLE COUNTER
DECLARE #sql nvarchar(999) --RAW SCORE FIELD
DECLARE #cpct float --CALCULATED PERCENT
DECLARE #scrt integer --TOP SCORE
DECLARE #scrf nvarchar(10) --RAW SCORE FIELD
DECLARE #scrr integer --ROUND RAW SCORE
DECLARE #scrs integer --SUMMED RAW SCORE
--SET VARIABLES
SET #cpct = #pct * .01
SET #scrt = (SELECT points FROM league WHERE id = #lid)
--LOOP THROUGH SCORES FROM 1 ON UP
SET #c = 1
SET #scrs = 0
WHILE (#c <= 30)
BEGIN
SET #scrf = 'round' + CAST(#c AS nvarchar(2))
SELECT #scrr =(SELECT #scrf FROM league_lineup WHERE id = #lrid)
SET #scrs = #scrs+#scrr
IF #c > #rds
PRINT 'ROUND ' + CAST(#c AS nvarchar(3)) + ' - SCORE: ' + CAST(#scrs AS nvarchar(5))
SET #c = #c + 1
END
...doesn't work....
Your basic problem is that in TSQL, data is never evaluated as though it weren't data*. That means this is what's happening is similar to that below:
SET #c = 25.48;
SET #scrf = 'round' + CAST(#c AS nvarchar(2));
The value of #scrf is now 'round25.48'. That means that this:
SELECT #scrr = (SELECT #scrf FROM league_lineup WHERE id = #lrid)
Is equivalent to this:
SELECT #scrr =(SELECT 'round25.48' FROM league_lineup WHERE id = #lrid)
Which means you're trying to assign the string (nvarchar) 'round25.48'to #scrr, an integer variable. So you get a conversion error.
You'll want to do something more like:
SELECT #scrr = (SELECT ROUND(#c) FROM league_lineup WHERE id = #lrid);
Finally, be careful with loops in SQL. Chances are you don't actually need it.
*Data can be evaluated as though it were SQL with special functions like EXEC(), but those are exceptions. Any anyways the data must be evaluated as an entire statement and not a fragment.
You should use dynamic query with output parameter in this situation:
Change
SELECT #scrr =(SELECT #scrf FROM league_lineup WHERE id = #lrid)
SET #scrs = #scrs+#scrr
to
DECLARE #sql = 'SELECT #scrr = ' + #scrf + ' FROM league_lineup WHERE id = #lrid'
EXEC sp_executesql #sql, N'#scrr int OUTPUT, #lrid int', #scrr OUTPUT, #lrid
SET #scrs = #scrs+#scrr

T-SQL Convert Hex to decimal

I try to use TSQL and I get some problem to convert hex to decimal when the value is inside a variable.
My code is:
SET #hex = SUBSTRING(#x,1,2) --give 1e
SET #hex = '0x' + #hex
SELECT CAST (#hex AS int)
I get the error that the conversion failed when converting the varchar value to int
I don't know what it's wrong and so far I can't find solution
Any idea? Thanks
This works (for SQL Server 2008 or later):
declare #hex varchar(316)
SET #hex = '1e' --SUBSTRING(#x,1,2) --give 1e
SET #hex = '0x' + #hex
SELECT CONVERT(int,CONVERT (binary(1),#hex,1))
See "Binary Styles" on the CAST and CONVERT page.
I don't think T-SQL can explicitly convert a string of hex to a number, but it CAN convert a hex number so you can kind of trick it into doing what you want. Like this:
DECLARE #hex nvarchar(20)
DECLARE #select nvarchar(200)
DECLARE #parm nvarchar(200)
DECLARE #retVal int
SET #hex = '0x1e'
SET #select = 'SELECT #retVal = CAST(' + #hex + ' AS int)'
SET #parm = '#retVal int OUTPUT'
EXEC sp_executesql #select, #parm, #retVal OUTPUT
SELECT #retVal
You'll want to validate #hex to protect from SQL injection attacks, and you'll probably want to put this in a function or stored proc
CREATE FUNCTION dbo.FN_HEXTOINT(#HEX varchar(MAX) = NULL)
RETURNS #RETORNO TABLE(INTHEX INT)
AS
BEGIN
SET #HEX = UPPER(#HEX)
DECLARE #TABHEX VARCHAR(16) = '0123456789ABCDEF'
DECLARE #CHARX VARCHAR(1)
DECLARE #POSCHARX INT
DECLARE #BASE INT = 16
DECLARE #I INT = LEN(#HEX)
DECLARE #LENSTR INT = LEN(#HEX)
DECLARE #EXPOENTE INT = 36
DECLARE #N10 FLOAT = 0.01
WHILE (#I> 0)
BEGIN
SET #CHARX = SUBSTRING (#HEX, #i,1)
SET #POSCHARX = PATINDEX('%'+#CHARX+'%', #TABHEX);
IF #POSCHARX > 0
BEGIN
SET #N10 = #N10 + ((#POSCHARX - 1) * POWER(#BASE, (#LENSTR-#I)))
END
SET #I = #I - 1
END
INSERT INTO #RETORNO
SELECT (ROUND(#N10 + 0.001,1)) AS RET
RETURN
END

Convert Hijri Shamsi date format tsql

I want convert my Hijri Shamsi date '92/2/3' to this format : '92/02/03'
With this code, I get this error :The conversion of a varchar data type to a datetime data type resulted in an out-of-range value.
Declare #Str Varchar(10) = '92/2/3'
Select Convert(Varchar(10), Convert(DateTime, #Str), 111)
How can i change format of date ?
Since you don't have centuries you should use 11, not 111 as your conversion code
You need to use 11 in the inner convert to tell it what format it is converting FROM
Declare #Str Varchar(10) = '92/2/3'
Select Convert(Varchar(10), Convert(DateTime, #Str,11), 11)
Use this functions to convert Gregorian date to Hijri(Shamsi) date with your requested format:
CREATE FUNCTION [dbo].[ShamsiDate]
(
#ChirsDate SMALLDATETIME
)
RETURNS CHAR(10)
AS
BEGIN
DECLARE #SolarDate CHAR(10)
DECLARE #Day CHAR(2)
DECLARE #Mon CHAR(2)
DECLARE #SDay INT
DECLARE #SMon INT
DECLARE #SYear INT
SET #SYear = dbo.ShamsiDatePart(#ChirsDate, 'Y')
SET #SMon = dbo.ShamsiDatePart(#ChirsDate, 'M')
SET #SDay = dbo.ShamsiDatePart(#ChirsDate, 'D')
IF #SMon <= 9
SELECT #Mon = '0' + CONVERT(CHAR(1), #SMon)
ELSE
SELECT #Mon = CONVERT(CHAR(2), #SMon)
IF #SDay <= 9
SELECT #Day = '0' + CONVERT(CHAR(1), #SDay)
ELSE
SELECT #Day = CONVERT(CHAR(2), #SDay)
SELECT #SolarDate = CONVERT(CHAR(4), #SYear) + '/' + #Mon + '/'
+ #Day
RETURN #SolarDate
END
CREATE FUNCTION [dbo].[ShamsiDatePart]
(
#MiDate DATETIME ,
#ADatePart CHAR
)
RETURNS INT
AS
BEGIN
DECLARE #TmpY INT ,
#Leap INT
DECLARE #Sh_Y INT ,
#Sh_M INT ,
#Sh_D INT ,
#Result INT
IF #MiDate IS NULL
RETURN 0
DECLARE #Result INT
SET #Result = CONVERT(INT, CONVERT(FLOAT, #MiDate))
IF #Result <= 78
BEGIN
SET #Sh_Y = 1278
SET #Sh_M = ( #Result + 10 ) / 30 + 10
SET #Sh_D = ( #Result + 10 ) % 30 + 1
END
ELSE
BEGIN
SET #Result = #Result - 78
SET #Sh_Y = 1279
WHILE 1 = 1
BEGIN
SET #TmpY = #Sh_Y + 11
SET #TmpY = #TmpY - ( #TmpY / 33 ) * 33
IF ( #TmpY <> 32 )
AND ( ( #TmpY / 4 ) * 4 = #TmpY )
SET #Leap = 1
ELSE
SET #Leap = 0
IF #Result <= ( 365 + #Leap )
BREAK
SET #Result = #Result - ( 365 + #Leap )
SET #Sh_Y = #Sh_Y + 1
END
IF #Result <= 31 * 6
BEGIN
SET #Sh_M = ( #Result - 1 ) / 31 + 1
SET #Sh_D = ( #Result - 1 ) % 31 + 1
END
ELSE
BEGIN
SET #Sh_M = ( ( #Result - 1 ) - 31 * 6 ) / 30 + 7
SET #Sh_D = ( ( #Result - 1 ) - 31 * 6 ) % 30 + 1
END
END
RETURN CASE #ADatePart WHEN 'Y' THEN #Sh_Y WHEN 'M' THEN #Sh_M WHEN 'D' THEN #Sh_D ELSE 0 END
END
You can use the give below solution, if you are using SQL Server 2012.
Declare #Str varchar(10) = '92/2/3'
Select Format(Convert(Date, #Str,11),'yy/MM/dd')
Imran

SQL Scalar UDF to get number of days in Year

I writing code to determine how many days in a year. I am trying to keep it really simple.
I found code that I think is very clean to determine a leap year. I am passing the inputted date using DATEPART(Y,#Year) to the leap year program and some how am not getting the correct results so I has to be in my SQL code to process the input date as the correct bit is returned.
Here is the code for the Leap Year:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[FN_Is_Leap_Year]
(
-- the parameters for the function here
#year int
)
RETURNS BIT
AS
BEGIN
RETURN (select case datepart(mm, dateadd(dd, 1, cast((cast(#year as varchar(4)) + '0228') as datetime)))
WHEN 2 THEN 1
ELSE 0 END)
END
Here is the code I wrote to process the input date & get the # days in a year:
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[FN_Get_Days_In_Year]
(
#InputDT varchar(10)
)
RETURNS int
AS
BEGIN
DECLARE #Result int,
#Year int
Set #Result =
CASE
WHEN dbo.FN_Is_Leap_Year(Datepart(yyyy,#Year)) = 0 Then 365
WHEN dbo.FN_Is_Leap_Year(Datepart(yyyy,#Year)) = 1 Then 366
END
RETURN #Result
END
Got it working!!
GO
ALTER FUNCTION [dbo].[FN_Get_Days_In_Year]
(
#InputDT int
)
RETURNS varchar(3)
AS
BEGIN
Declare #Year int,
#RetVal bit,
#Result varchar(3)
Set #Year = datepart(yy, #InputDT)
Set #RetVal = dbo.FN_Is_Leap_Year(Datepart(yy,'2012'))
Set #Result = CASE #RetVal
WHEN 1 THEN 366
ELSE 365
End
Return #Result
END
Modified version of the above answer :
DECLARE #year INT,
#DaysInYear INT
SET #year = 2011
SELECT #DaysInYear = CASE DATEPART(mm, DATEADD(dd, 1, CAST((CAST(#year AS VARCHAR(4)) + '0228') AS DATETIME)))
WHEN 2 THEN 366 ELSE 365 END
SELECT #DaysInYear 'DaysInYear'