Create a existing SQL table valued function to Oracle - sql

I have a table valued function created in SQL that gives me a list of values for each month based upon the dates passed as parameters. It works fine when I execute in SQL server but I need to create a similar function in Oracle as well. I am not familiar with Oracle code so could anyone please help in letting me know how to convert the function into an oracle function??
The function in SQL is as follows :
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[ES_REPORT_PSH_FISCALANALYSIS_FUNCTION]
(#P_AUTHORITY VARCHAR (100) = '',
#P_STARTDATE DATETIME = '',
#P_ENDDATE DATETIME = '',
#P_CLOSEDREASONS VARCHAR (100) = '',
#P_GRANTTYPES VARCHAR (100) = '')
RETURNS #RETURNTABLE TABLE(GRTYPE VARCHAR(100),
GRTYPEDESC VARCHAR(200),
TASK VARCHAR(100),
TASKDESC VARCHAR(100),
PERIODTEXT VARCHAR(100),
COUNT_DTRECD INT,
COUNT_DTSCHD INT,
COUNT_DTAPLMADE INT,
COUNT_DTAPPR INT,
COUNT_DTCMPLTD INT,
COUNT_DTCLOSED INT,
SUM_GRANTVALUE MONEY,
VAL_PAYMENTS MONEY)
AS
BEGIN
DECLARE #RETURNTABLE_1 TABLE
(
GRTYPE VARCHAR(100),
GRTYPEDESC VARCHAR(200),
TASK VARCHAR(100),
TASKDESC VARCHAR(100),
PERIODTEXT VARCHAR(100),
COUNT_DTRECD INT,
COUNT_DTSCHD INT,
COUNT_DTAPLMADE INT,
COUNT_DTAPPR INT,
COUNT_DTCMPLTD INT,
COUNT_DTCLOSED INT,
SUM_GRANTVALUE MONEY,
VAL_PAYMENTS MONEY
)
--populate default values;
declare #tmpDate DATETIME
declare #perText VARCHAR(100)
DECLARE #GTT_SPLIT_VALUES TABLE(ROW INT, VALUE VARCHAR(100))
INSERT INTO #GTT_SPLIT_VALUES SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS ROW,VAL FROM [DBO].[SPLITVALUES](#P_GRANTTYPES, ',')
DECLARE #counter INT = 1
DECLARE #max INT = (SELECT COUNT(*) FROM #GTT_SPLIT_VALUES)
DECLARE #thisGR VARCHAR(50)
DECLARE #thisGR1 VARCHAR(100)
WHILE #counter <= #max
BEGIN
SET #thisGR = (SELECT VALUE FROM #GTT_SPLIT_VALUES where ROW = #Counter)
SET #thisGR1 = (SELECT TOP 1 TASKDESC FROM PPV_GRANTS pv1 LEFT JOIN #GTT_SPLIT_VALUES pv on pv.VALUE = pv1.TASK where ROW = #Counter)
SET #tmpDate = #P_STARTDATE
WHILE (#tmpDate < #P_ENDDATE)
BEGIN
SET #perText = DATENAME(month, #tmpDate) + ' ' + DATENAME(year, #tmpDate)
INSERT INTO #RETURNTABLE select #thisGR,#thisGR,#thisGR,#thisGR1,#perText,0,0,0,0,0,0,0,0 from dual
SET #tmpDate = DATEADD(month, 1, #tmpDate)
END
SET #counter = #counter + 1
END
--logic in here
declare crGrants CURSOR for select PG.GRTYPE, PG.GRTYPEDESC,PG.TASK,PG.TASKDESC, PG.DTRECD, PG.DTSCHD, PG.DTAPLMADE, PG.DTAPPR, PG.DTCMPLTD,PG.DTCLOSED,PG.GRANTVALUE,PGP.VALUE,PGP.PAYMENTDATE
from dbo.PPV_GRANTS PG
LEFT JOIN PPV_GRANT_PAYMENTS PGP ON PGP.WORKID = PG.WORKID
order by PG.WORKID
declare #GRTYPE VARCHAR(4)
declare #GRTYPEDESC VARCHAR(50)
declare #TASK VARCHAR(100)
declare #TASKDESC VARCHAR(100)
declare #DTRECD DATETIME
declare #DTSCHD DATETIME
declare #DTAPLMADE DATETIME
declare #DTAPPR DATETIME
declare #DTCMPLTD DATETIME
declare #DTCLOSED DATETIME
declare #MONTHTXT VARCHAR(20)
declare #GRANTVALUE FLOAT
declare #Value FLOAT
declare #PaymentDate DATETIME
open crGrants
FETCH NEXT FROM crGrants INTO #GRTYPE, #GRTYPEDESC,#TASK,#TASKDESC, #DTRECD, #DTSCHD, #DTAPLMADE, #DTAPPR, #DTCMPLTD, #DTCLOSED,#GRANTVALUE, #Value, #PaymentDate
WHILE ##FETCH_STATUS = 0
BEGIN
IF (#DTRECD >= #P_STARTDATE AND #DTRECD <= #P_ENDDATE)
BEGIN
SET #perText = DATENAME(month, #DTRECD) + ' ' + DATENAME(year, #DTRECD)
UPDATE #RETURNTABLE SET COUNT_DTRECD = COUNT_DTRECD + 1
WHERE GRTYPE = #GRTYPE and PERIODTEXT = #perText
END
IF (#DTSCHD >= #P_STARTDATE AND #DTSCHD <= #P_ENDDATE)
BEGIN
SET #perText = DATENAME(month, #DTSCHD) + ' ' + DATENAME(year, #DTSCHD)
UPDATE #RETURNTABLE SET COUNT_DTSCHD = COUNT_DTSCHD + 1
WHERE GRTYPE = #GRTYPE and PERIODTEXT = #perText
END
IF (#DTAPLMADE >= #P_STARTDATE AND #DTAPLMADE <= #P_ENDDATE)
BEGIN
SET #perText = DATENAME(month, #DTAPLMADE) + ' ' + DATENAME(year, #DTAPLMADE)
UPDATE #RETURNTABLE SET COUNT_DTAPLMADE = COUNT_DTAPLMADE + 1
WHERE GRTYPE = #GRTYPE and PERIODTEXT = #perText
END
IF (#DTAPPR >= #P_STARTDATE AND #DTAPPR <= #P_ENDDATE)
BEGIN
SET #perText = DATENAME(month, #DTAPPR) + ' ' + DATENAME(year, #DTAPPR)
UPDATE #RETURNTABLE SET COUNT_DTAPPR = COUNT_DTAPPR + 1
WHERE GRTYPE = #GRTYPE and PERIODTEXT = #perText
END
IF (#DTCMPLTD >= #P_STARTDATE AND #DTCMPLTD <= #P_ENDDATE)
BEGIN
SET #perText = DATENAME(month, #DTCMPLTD) + ' ' + DATENAME(year, #DTCMPLTD)
UPDATE #RETURNTABLE SET COUNT_DTCMPLTD = COUNT_DTCMPLTD + 1
WHERE GRTYPE = #GRTYPE and PERIODTEXT = #perText
END
IF (#DTCLOSED >= #P_STARTDATE AND #DTCLOSED <= #P_ENDDATE)
BEGIN
SET #perText = DATENAME(month, #DTCLOSED) + ' ' + DATENAME(year, #DTCLOSED)
UPDATE #RETURNTABLE SET COUNT_DTCLOSED = COUNT_DTCLOSED + 1
WHERE GRTYPE = #GRTYPE and PERIODTEXT = #perText
END
IF (#DTAPPR >= #P_STARTDATE AND #DTAPPR <= #P_ENDDATE)
BEGIN
SET #perText = DATENAME(month, #DTAPPR) + ' ' + DATENAME(year, #DTAPPR)
UPDATE #RETURNTABLE SET SUM_GRANTVALUE = #GRANTVALUE
WHERE GRTYPE = #GRTYPE and PERIODTEXT = #perText
END
IF (#PaymentDate >= #P_STARTDATE AND #PaymentDate <= #P_ENDDATE)
BEGIN
SET #perText = DATENAME(month, #PaymentDate) + ' ' + DATENAME(year, #PaymentDate)
UPDATE #RETURNTABLE SET VAL_PAYMENTS = #Value
WHERE GRTYPE = #GRTYPE and PERIODTEXT = #perText
END
FETCH NEXT FROM crGrants INTO #GRTYPE, #GRTYPEDESC,#TASK,#TASKDESC, #DTRECD, #DTSCHD, #DTAPLMADE, #DTAPPR, #DTCMPLTD, #DTCLOSED , #GRANTVALUE , #Value , #PaymentDate
END
close crGrants
deallocate crGrants
--result set
RETURN
END

Related

How to specify the value of the selected field with type date displayed Jalali (Shamsi) instead of date miladi (Gregorian Date) [duplicate]

I want to convert my datetime into Persian datetime in SQL Server. My datetime is in MM/DD/YYYY format. Is there any function in SQL Server to do this as when I want hijri datetime I use this
SELECT CONVERT(VARCHAR(40), GETDATE(), 131) -- Output is 14/08/1432 5:02:01:197PM
I'm using SQL Server 2008.
Best method in SQL Server 2016
Example:
SELECT FORMAT(GETDATE(), 'yyyy/MM/dd-HH:mm:ss', 'fa')
Answer:
1398/10/08-05:37:59
I know it is too late for answering this question, but I've submitted the function that I'm using for a long time without any bug, all of other methods which I've ever seen have problem with intercalary years:
CREATE FUNCTION [CalculatePersianDate] ( #intDate DATETIME )
RETURNS NVARCHAR(max)
BEGIN
DECLARE #shYear AS INT ,#shMonth AS INT ,#shDay AS INT ,#intYY AS INT ,#intMM AS INT ,#intDD AS INT ,#Kabiseh1 AS INT ,#Kabiseh2 AS INT ,#d1 AS INT ,#m1 AS INT, #shMaah AS NVARCHAR(max),#shRooz AS NVARCHAR(max),#DayCnt AS INT
DECLARE #DayDate AS NVARCHAR(max)
SET #intYY = DATEPART(yyyy, #intDate)
IF #intYY < 1000 SET #intYY = #intYY + 2000
SET #intMM = MONTH(#intDate)
SET #intDD = DAY(#intDate)
SET #shYear = #intYY - 622
SET #DayCnt = 5
IF ( ( #intYY - 1992 ) % 4 = 0) SET #Kabiseh1 = 0 ELSE SET #Kabiseh1 = 1
IF ( ( #shYear - 1371 ) % 4 = 0) SET #Kabiseh2 = 0 ELSE SET #Kabiseh2 = 1
SET #m1 = 1
SET #d1 = 1
SET #shMonth = 10
SET #shDay = 11
IF ( ( #intYY - 1993 ) % 4 = 0 ) SET #shDay = 12
WHILE ( #m1 != #intMM ) OR ( #d1 != #intDD )
BEGIN
SET #d1 = #d1 + 1
SET #DayCnt = #DayCnt + 1
IF
(#d1 = 32 AND (#m1 = 1 OR #m1 = 3 OR #m1 = 5 OR #m1 = 7 OR #m1 = 8 OR #m1 = 10 OR #m1 = 12))
OR
(#d1 = 31 AND (#m1 = 4 OR #m1 = 6 OR #m1 = 9 OR #m1 = 11))
OR
(#d1 = 30 AND #m1 = 2 AND #Kabiseh1 = 1)
OR
(#d1 = 29 AND #m1 = 2 AND #Kabiseh1 = 0)
BEGIN
SET #m1 = #m1 + 1
SET #d1 = 1
END
IF #m1 > 12
BEGIN
SET #intYY = #intYY + 1
SET #m1 = 1
END
IF #DayCnt > 7 SET #DayCnt = 1
SET #shDay = #shDay + 1
IF
(#shDay = 32 AND #shMonth < 7)
OR
(#shDay = 31 AND #shMonth > 6 AND #shMonth < 12)
OR
(#shDay = 31 AND #shMonth = 12 AND #Kabiseh2 = 1)
OR
(#shDay = 30 AND #shMonth = 12 AND #Kabiseh2 = 0)
BEGIN
SET #shMonth = #shMonth + 1
SET #shDay = 1
END
IF #shMonth > 12
BEGIN
SET #shYear = #shYear + 1
SET #shMonth = 1
END
END
IF #shMonth=1 SET #shMaah=N'فروردین'
IF #shMonth=2 SET #shMaah=N'اردیبهشت'
IF #shMonth=3 SET #shMaah=N'خرداد'
IF #shMonth=4 SET #shMaah=N'تیر'
IF #shMonth=5 SET #shMaah=N'مرداد'
IF #shMonth=6 SET #shMaah=N'شهریور'
IF #shMonth=7 SET #shMaah=N'مهر'
IF #shMonth=8 SET #shMaah=N'آبان'
IF #shMonth=9 SET #shMaah=N'آذر'
IF #shMonth=10 SET #shMaah=N'دی'
IF #shMonth=11 SET #shMaah=N'بهمن'
IF #shMonth=12 SET #shMaah=N'اسفند'
IF #DayCnt=1 SET #shRooz=N'شنبه'
IF #DayCnt=2 SET #shRooz=N'یکشنبه'
IF #DayCnt=3 SET #shRooz=N'دوشنبه'
IF #DayCnt=4 SET #shRooz=N'سه‌شنبه'
IF #DayCnt=5 SET #shRooz=N'چهارشنبه'
IF #DayCnt=6 SET #shRooz=N'پنجشنبه'
IF #DayCnt=7 SET #shRooz=N'جمعه'
--SET #DayDate = #shRooz + " " + LTRIM(STR(#shDay,2)) + " " + #shMaah + " " + STR(#shYear,4)
--پنجشنبه 17 اردیبهشت 1394
/*
SET #DayDate = LTRIM(STR(#shDay,2)) + " " + #shMaah + " " + STR(#shYear,4)
--17 اردیبهشت 1394
SET #DayDate = STR(#shYear,4) + "/"+LTRIM(STR(#shMonth,2)) + "/" + LTRIM(STR(#shDay,2))
--1394/2/17
--1394/02/17
*/
SET #DayDate = REPLACE(RIGHT(STR(#shYear, 4), 4), ' ', '0') + '/'+ REPLACE(STR(#shMonth, 2), ' ', '0') + '/' + REPLACE(( STR(#shDay,2) ), ' ', '0')
RETURN #DayDate
END
It is really easy to customize the result of the function.
adopted from: this page
I know it is too late but maybe useful for others like me having this trouble.
You should write a SQL Function for this conversion like this:
Converting Gregorian to Persian Date
and then use it like this:
SELECT dbo.[UDF_Gregorian_To_Persian]('2013-08-24')
Try this:
select format(getdate() , 'yyyy/MM/dd', 'fa-ir')
You can use the following code to convert the date. This practical and important method has been added to the 2012 version of SQL and can be used.
SELECT FORMAT(GETDATE(), 'yyyy/MM/dd-HH:mm:ss', 'fa')
Result: 1400/02/08-05:08:51
SELECT cast( FORMAT(GETDATE(), 'yyyyMMdd', 'fa') as int)
Result: 14000208
And you can use Format as Follow to get Higri Date:
SELECT FORMAT(GETDATE(), N'yyyy/MM/dd', N'ar')
Result: 1443/06/19
Out of the box, no.
You'd have to write your own UDF, however there is one on CodePlex and another
I believe the best available solution is to use SQLCLR-Jalali-Date-Utility. It has a straightforward installation guide and easy to use functions. Moreover, you can define the format of the converted date without any limitation. in fact, you can use the standard time formatting to define the shape of converted dates.
There are several examples provided inside the GitHub page.
select dbo.GregorianToJalali(GETDATE(),'yyyy/MM/dd hh:mm:ss tt') -- returns 1395/07/01 03:04:33 ب ظ
this is persian Calendar function in SQL 2016+
ALTER FUNCTION [dbo].[PCalendar](#date datetime)
RETURNS #ret TABLE (
ly int,
y int,
m int,
mname nvarchar(15),
d int,
dy int,
dw int,
dname nvarchar(10),
hh int,
mm int,
ss int,
mss int,
dt datetime,
t nvarchar(3))
as
BEGIN
DECLARE #format varchar(19);
set #format = 'yyyy/MM/dd HH:mm:ss';
DECLARE #y int;
DECLARE #m int;
DECLARE #d int;
DECLARE #dy int;
DECLARE #dw int;
DECLARE #hh int;
DECLARE #mm int;
DECLARE #ss int;
DECLARE #ms int;
DECLARE #ldt varchar(8);
set #y = DATEPART(YEAR, FORMAT(#date, #format, 'fa')) ;
set #m = DATEPART(MONTH, FORMAT(#date, #format, 'fa'));
set #d = DATEPART(DAY, FORMAT(#date, #format, 'fa')) ;
set #dy = DATEPART(DAYOFYEAR, FORMAT(#date, #format, 'fa'));
set #dw = DATEPART(WEEKDAY, FORMAT(#date,#format, 'fa'));
set #hh = DATEPART(HOUR, #date) ;
set #mm = DATEPART(MINUTE, #date) ;
set #ss = DATEPART(SECOND, #date);
set #ms = DATEPART(MILLISECOND, #date);
set #ldt =DATEPART(year, FORMAT(#date, #format, 'en'));
DECLARE #_w nvarchar(10);
set #_w = CASE
WHEN #dw=1 THEN N'جمعه'
WHEN #dw=2 THEN N'شنبه'
WHEN #dw=3 THEN N'یکشنبه'
WHEN #dw=4 THEN N'دوشنبه'
WHEN #dw=5 THEN N'سه شنبه'
WHEN #dw=6 THEN N'چهارشنبه'
ELSE N'پنج شنبه'
END;
DECLARE #_m nvarchar(15);
set #_m = CASE
WHEN #m=1 THEN N'فروردین'
WHEN #m=2 THEN N'اردیبهشت'
WHEN #m=3 THEN N'خرداد'
WHEN #m=4 THEN N'تیر'
WHEN #m=5 THEN N'مرداد'
WHEN #m=6 THEN N'شهریور'
WHEN #m=7 THEN N'مهر'
WHEN #m=8 THEN N'آبان'
WHEN #m=9 THEN N'آذر'
WHEN #m=10 THEN N'دی'
WHEN #m=11 THEN N'بهمن'
ELSE N'اسفند'
END;
set #_m = #_m+N' ماه';
INSERT INTO #ret
SELECT
IIF(#y % 33 in (1,5,9,13,17,22,26,30) , 1 , 0) as ly,
#y as y,
#m as m,
#_m as mname,
#d as d,
#dy as dy,
#dw as dw,
#_w as dname,
#hh as hh,
#mm as mm,
#ss as ss,
#ms as mss,
#date as dt,
IIF(#hh > 12 , N'ب.ظ','ق.ظ') as t;
RETURN;
END
You can convert it to shamsi using this functions.
The first function.
CREATE FUNCTION [dbo].[ToPersianDate](#dt [datetime])
RETURNS [nvarchar](10) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [PersianSQLFunctions].[UserDefinedFunctions].[ToPersianDate]
GO
second function.
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
CREATE FUNCTION [dbo].[ToPersianDate](#dt [datetime])
RETURNS [nvarchar](10) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [PersianSQLFunctions].[UserDefinedFunctions].[ToPersianDate]
GO
third function.
CREATE FUNCTION [dbo].[fnToShamsiDate]
(
#d DateTime
)
RETURNS NVARCHAR(10)
AS
BEGIN
-- Declare the return variable here
DECLARE #RV NVARCHAR(10)
IF (#d) IS NULL RETURN NULL;
ELSE SELECT #RV = DBO.ToPersianDate(#D);
-- Return the result of the function
RETURN #RV
END
GO
And also you can find shamsi months from this function
create function [dbo].[fnGetShamsiMonth]
(
#GregorianDate date
)
returns nvarchar(2)
as
begin
declare #ShamsiMonth nvarchar(2), #ShamsiDate nvarchar(10);
set #ShamsiDate = confsys.dbo.fnToShamsiDate(#GregorianDate);
set #ShamsiMonth = SUBSTRING(#ShamsiDate,6,2);
return #ShamsiMonth
end
GO
examples
select confsys.dbo.fnToShamsiDate(getdate())
result is 1397/12/29
get shamsi months
select confsys.dbo.fnGetShamsiMonth(GETDATE());
Function : Full Convert Persian (Shamsi / Jalali ) String to Gregorian (miladi) Datetime in sql server :
> create or ALTER Function [dbo].[Func_ShamsiToMiladi] (#Date
> Varchar(23) ) RETURNS DateTime BEGIN
> -- ==============================================================
> -- SELECT [dbo].[Func_ShamsiToMiladi] ('1356-09-20 05:35:00.000')
> --
> -- Output : '1977-12-11 02:05:00.000'
> -- ==============================================================
> -- BY: Shahrokh Vazifedan Hobabname#Gmail.COM DECLARE #PersianDate Varchar(23) SET #PersianDate = #Date
>
> DECLARE #Year INT = SUBSTRING(#PersianDate, 1, 4)
> DECLARE #Month INT = SUBSTRING(#PersianDate, 6, 2)
> DECLARE #Day INT = SUBSTRING(#PersianDate, 9, 2)
> DECLARE #DiffYear INT = #Year - 1350
> DECLARE #Time varchar(13) = SUBSTRING(#PersianDate, 11, 13)
>
>
> DECLARE #Days INT = #DiffYear * 365.24 +
> CASE WHEN #Month < 7 THEN (#Month - 1) * 31
> ELSE 186 + (#Month - 7) * 30 END + #Day
>
> DECLARE #StartDate DATETIME = '03/21/1971'
> DECLARE #ResultDate DATE = #StartDate + #Days
>
> DECLARE #TempDate varchar(23) = Convert( Nvarchar(10) , #ResultDate ,120) + #Time DECLARE #OffSET_First_half_in_Year
> INT; SET #OffSET_First_half_in_Year = iif( Substring(Convert(
> Nvarchar(50), #TempDate,120) ,6,16) Between '03-20 20:30' and '09-22
> 20:30' , -60 ,0)
> RETURN dateadd(MINUTE, #OffSET_First_half_in_Year + (-1)*datediff(MINUTE, getutcdate(), getdate()),#TempDate ) END
Created By : Shahrokh Vazifedan -Sari # Iran :)
Email: HobabName#Gmail.com
CREATE FUNCTION [dbo].[MITSH] (#MDate DateTime)
RETURNS Varchar(10)
AS
BEGIN
DECLARE #SYear as Integer
DECLARE #SMonth as Integer
DECLARE #my_mah varchar(2)
declare #my_day varchar(2)
DECLARE #SDay as Integer
DECLARE #AllDays as float
DECLARE #ShiftDays as float
DECLARE #OneYear as float
DECLARE #LeftDays as float
DECLARE #YearDay as Integer
DECLARE #Farsi_Date as Varchar(100)
SET #MDate=#MDate-CONVERT(char,#MDate,114)
SET #ShiftDays=466699 +2
SET #OneYear= 365.24199
SET #SYear = 0
SET #SMonth = 0
SET #SDay = 0
SET #AllDays = CAst(#Mdate as Real)
SET #AllDays = #AllDays + #ShiftDays
SET #SYear = (#AllDays / #OneYear) --trunc
SET #LeftDays = #AllDays - #SYear * #OneYear
if (#LeftDays < 0.5)
begin
SET #SYear=#SYear+1
SET #LeftDays = #AllDays - #SYear * #OneYear
end;
SET #YearDay = #LeftDays --trunc
if (#LeftDays - #YearDay) >= 0.5
SET #YearDay=#YearDay+1
if ((#YearDay / 31) > 6 )
begin
SET #SMonth = 6
SET #YearDay=#YearDay-(6 * 31)
SET #SMonth= #SMonth+( #YearDay / 30)
if (#YearDay % 30) <> 0
SET #SMonth=#SMonth+1
SET #YearDay=#YearDay-((#SMonth - 7) * 30)
end
else
begin
SET #SMonth = #YearDay / 31
if (#YearDay % 31) <> 0
SET #SMonth=#SMonth+1
SET #YearDay=#YearDay-((#SMonth - 1) * 31)
end
SET #SDay = #YearDay
SET #SYear=#SYear+1
if #SMonth <10 begin
set #my_mah='0'+str(#SMonth,1)
end else begin
set #my_mah = str(#SMonth,2)
end
if #sday <10 begin
set #my_day='0'+str(#Sday,1)
end else begin
set #my_day = str(#Sday,2)
end
SET #Farsi_Date = CAST (#SYear as VarChar(10)) + '/' + #my_mah + '/' + #my_day
Return #Farsi_Date
END
AN FOR EXEC FUNCTION
SELECT DBO.MITSH(GETDATE())
for example date is 2020-09-25
resualt =>>>> 1399/07/04
Complete Function For Shamsi date for SQL 2008 and 2008 R2 and below versions:
CREATE FUNCTION [dbo].[PersToJul](#iYear int,#iMonth int,#iDay int)
RETURNS bigint
AS
Begin
Declare #PERSIAN_EPOCH as int
Declare #epbase as bigint
Declare #epyear as bigint
Declare #mdays as bigint
Declare #Jofst as Numeric(18,2)
Declare #jdn bigint
Set #PERSIAN_EPOCH=1948321
Set #Jofst=2415020.5
If #iYear>=0
Begin
Set #epbase=#iyear-474
End
Else
Begin
Set #epbase = #iYear - 473
End
set #epyear=474 + (#epbase%2820)
If #iMonth<=7
Begin
Set #mdays=(Convert(bigint,(#iMonth) - 1) * 31)
End
Else
Begin
Set #mdays=(Convert(bigint,(#iMonth) - 1) * 30+6)
End
Set #jdn =Convert(int,#iday) + #mdays+ Cast(((#epyear * 682) - 110) / 2816 as int) + (#epyear - 1) * 365 + Cast(#epbase / 2820 as int) * 1029983 + (#PERSIAN_EPOCH - 1)
RETURN #jdn
End
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
CREATE FUNCTION [dbo].[GrToPers] (#date datetime)
Returns nvarchar(50)
AS
Begin
Declare #depoch as bigint
Declare #cycle as bigint
Declare #cyear as bigint
Declare #ycycle as bigint
Declare #aux1 as bigint
Declare #aux2 as bigint
Declare #yday as bigint
Declare #Jofst as Numeric(18,2)
Declare #jdn bigint
Declare #iYear As Integer
Declare #iMonth As Integer
Declare #iDay As Integer
Set #Jofst=2415020.5
Set #jdn=Round(Cast(#date as int)+ #Jofst,0)
Set #depoch = #jdn - [dbo].[PersToJul](475, 1, 1)
Set #cycle = Cast(#depoch / 1029983 as int)
Set #cyear = #depoch%1029983
If #cyear = 1029982
Begin
Set #ycycle = 2820
End
Else
Begin
Set #aux1 = Cast(#cyear / 366 as int)
Set #aux2 = #cyear%366
Set #ycycle = Cast(((2134 * #aux1) + (2816 * #aux2) + 2815) / 1028522 as int) + #aux1 + 1
End
Set #iYear = #ycycle + (2820 * #cycle) + 474
If #iYear <= 0
Begin
Set #iYear = #iYear - 1
End
Set #yday = (#jdn - [dbo].[PersToJul](#iYear, 1, 1)) + 1
If #yday <= 186
Begin
Set #iMonth = CEILING(Convert(Numeric(18,4),#yday) / 31)
End
Else
Begin
Set #iMonth = CEILING((Convert(Numeric(18,4),#yday) - 6) / 30)
End
Set #iDay = (#jdn - [dbo].[PersToJul](#iYear, #iMonth, 1)) + 1
Return Convert(nvarchar(50),#iDay) + '-' + Convert(nvarchar(50),#iMonth) +'-' + Convert(nvarchar(50),#iYear)
End
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
CREATE FUNCTION [dbo].[JulToGre] (#jdn bigint)
Returns nvarchar(11)
AS
Begin
Declare #Jofst as Numeric(18,2)
Set #Jofst=2415020.5
Return Convert(nvarchar(11),Convert(datetime,(#jdn- #Jofst),113),110)
End
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
CREATE FUNCTION [dbo].[COnvertOToN](#StrMyNum NVARCHAR(2))
RETURNS NVARCHAR(2)
AS
BEGIN
DECLARE #MyNunInStr NVARCHAR(10)
SET #MyNunInStr = #StrMyNum
IF LEN(#MyNunInStr) < 2
BEGIN
SET #MyNunInStr = '0' + #MyNunInStr
END
RETURN #MyNunInStr
END
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
-- Changing Date Format
CREATE FUNCTION [dbo].[RevDateShm](#StrDateShamsi NVARCHAR(10), #Seperator CHAR(1))
RETURNS NVARCHAR(10)
AS
BEGIN
DECLARE #StrDayOfMotn NVARCHAR(10)
DECLARE #StrMothOfYear NVARCHAR(10)
DECLARE #StrYearOfYear NVARCHAR(10)
SET #StrDayOfMotn = dbo.COnvertOToN(REPLACE(SUBSTRING(#StrDateShamsi , 1 , ((SELECT CHARINDEX('-' , #StrDateShamsi , 0)))), '-' , ''))
SET #StrMothOfYear = dbo.COnvertOToN(REPLACE(SUBSTRING(#StrDateShamsi , ((CHARINDEX('-' , #StrDateShamsi , 0) )) , 3) , '-' , ''))
SET #StrYearOfYear = RIGHT(#StrDateShamsi , 4)
return (#StrYearOfYear + #Seperator + #StrMothOfYear + #Seperator + #StrDayOfMotn)
END
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
CREATE FUNCTION [dbo].[ConvertShamsiToMiladiDate](#InputShamsiDateString nvarchar(10))
RETURNS datetime
AS
BEGIN
declare #InputShamsiDateString1 nvarchar(10)
declare #yearm int
declare #monthm int
declare #daym int
set #yearm = CONVERT(int , SUBSTRING(#InputShamsiDateString , 1 , 4))
set #monthm = CONVERT(int , SUBSTRING(#InputShamsiDateString , 6 , 2))
set #daym = CONVERT(int , SUBSTRING(#InputShamsiDateString , 9 , 2))
return (select dbo.[JulToGre](dbo.[PersToJul](#yearm,#monthm ,#daym )))
END
--------------------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------------------
GO
-- The Latest And Main Function
CREATE FUNCTION [dbo].[GetShmsiDate](#InputMiladiDate DateTime , #MySeperatorChar char(1))
RETURNS NVARCHAR(10)
AS
BEGIN
return (select dbo.RevDateShm(dbo.GrToPers(#InputMiladiDate), #MySeperatorChar) AS ShamsiDateOfLog)
END
GO
How to use:
SELECT dbo.GetShmsiDate(GETDATE() , N'/') AS ShamsiDate1,
dbo.GetShmsiDate(GETDATE() , N'-') AS ShamsiDate2
Result:
|ShamsiDate1|ShamsiDate2|
|-----------|-----------|
|1400/11/03 | 1400-11-03|
To convert a date to persian, try this code:
DECLARE #DateString NVARCHAR(200)='2022/09/07';
SELECT FORMAT(CAST(#DateString AS DATE),'yyyy/MM/dd','fa');

Passing parametrs to dynamic query

I have a stored procedure as following, I need to pass paramters to the dynamic pivot. My query runs, I just need to do some filtering based on the passed parameters
-- AND (#SelectedSystemIDs IS NULL OR System.ID IN(select * from dbo.SplitInts_RBAR_1(#SelectedSystemIDs, ',')))
--AND ((#PlatformID IS NULL) OR (System.PlatformID = #PlatformID) OR (#PlatformID = 12 AND System.PlatformID <= 2))
-- AND (ServiceEntry.ServiceDateTime between #StartDate and #EndDate)
so I want to add the above criteria, how could achieve that?
ALTER PROCEDURE [dbo].[spExportStuff]
(#StartDate datetime,
#EndDate datetime,
#SelectedSystemIDs nvarchar (2000) = NULL,
#SelectedTsbIDs nvarchar (2000) = NULL,
#UserRoleID int
)
AS
DECLARE #InstrumentType int = NULL
DECLARE #PlatformID int = null
IF (#SelectedSystemIDs = '')
begin
SET #SelectedSystemIDs = NULL
END
IF (#SelectedTsbIDs = '')
begin
SET #SelectedTsbIDs = NULL
END
IF(#UserRoleID = 1)
BEGIN
SET #PlatformID = 1
END
IF(#UserRoleID = 2)
BEGIN
SET #PlatformID = 2
END
IF (#UserRoleID = 3)
BEGIN
SET #PlatformID = 12
END
IF(#UserRoleID = 4)
BEGIN
SET #PlatformID = 3
END
IF(#UserRoleID = 5)
BEGIN
SET #PlatformID = 4
END
IF(#UserRoleID = 6)
BEGIN
SET #PlatformID = NULL
END
DECLARE #PivotColumnHeaders NVARCHAR(MAX)
SELECT #PivotColumnHeaders =
COALESCE(
#PivotColumnHeaders + ',[' + cast(SystemFullName as Nvarchar) + ']',
'[' + cast(SystemFullName as varchar)+ ']'
)
FROM System
DECLARE #PivotTableSQL NVARCHAR(MAX)
SET #PivotTableSQL = N'
SELECT *
FROM (
SELECT
TSBNumber [TSBNumber],
SystemFullName,
ClosedDate
FROM ServiceEntry
INNER JOIN System
ON ServiceEntry.SystemID = System.ID
Group By TSBNumber, SystemFullName, ClosedDate
) AS PivotData
PIVOT (
max(ClosedDate)
FOR SystemFullName IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
'
EXECUTE(#PivotTableSQL)
you can construct the required criteria as another input to the stored procedure and append it to the dynamic query
ALTER PROCEDURE [dbo].[spExportStuff]
(#StartDate datetime,
#EndDate datetime,
#SelectedSystemIDs nvarchar (2000) = NULL,
#SelectedTsbIDs nvarchar (2000) = NULL,
#UserRoleID int,
#WhereClause varchar(max) -> this is the new parameter.
)
DECLARE #PivotTableSQL NVARCHAR(MAX)
SET #PivotTableSQL = N'
SELECT *
FROM (
SELECT
TSBNumber [TSBNumber],
SystemFullName,
ClosedDate
FROM ServiceEntry
INNER JOIN System
ON ServiceEntry.SystemID = System.ID
Group By TSBNumber, SystemFullName, ClosedDate
) AS PivotData
PIVOT (
max(ClosedDate)
FOR SystemFullName IN (
' + #PivotColumnHeaders + '
)
) AS PivotTable
' + #WhereClause -> you can append the where clause here.
EXECUTE(#PivotTableSQL)

Function returning null

ALTER FUNCTION [dbo].[getCourseCost]
(
#CourseCode varchar(50),
#Year nchar(10),
#Period nchar(10)
)
RETURNS int
AS
BEGIN
DECLARE #Pnr_personal varchar(50)
DECLARE #Timlön_personal int
DECLARE #Antal_timmar_personal int
DECLARE #Kostnad_personal int
DECLARE #Kostnad_labass int
SELECT #Pnr_personal = Personnummer FROM Bemannas_Av WHERE Period = #Period AND Läsår = #Year AND Kurskod = #CourseCode
SELECT #Timlön_personal = Timlön FROM Personal WHERE Personnummer = #Pnr_personal
SELECT #Antal_timmar_personal = Antal_Timmar FROM Bemannas_Av WHERE Period = #Period AND Läsår = #Year AND Kurskod = #CourseCode
SELECT #Kostnad_labass = (Antal_timmar * Timlön) FROM Labass WHERE Period = #Period AND Läsår = #Year AND Kurser = #CourseCode
SET #Kostnad_personal = #Timlön_personal * #Antal_timmar_personal
IF #Kostnad_personal = NULL
BEGIN
SET #Kostnad_personal = 0
END
IF #Kostnad_labass = NULL
BEGIN
SET #Kostnad_labass = 0
END
RETURN #Kostnad_personal + #Kostnad_labass
END
This keeps returning NULL even though none of the used values are NULL in the database.
This part has a problem #Kostnad_personal=null means nothing .
IF #Kostnad_personal is NULL
BEGIN
SET #Kostnad_personal = 0
END
IF #Kostnad_labass is NULL
BEGIN
SET #Kostnad_labass = 0
END
Or use this :
RETURN ISNULL(#Kostnad_personal,0) + ISNULL(#Kostnad_labass,0)

SQL code for anagram

I have a SQL code for finding whether two words are anagram or not.
DECLARE #str1 VARCHAR(100), #str2 VARCHAR(100)
SELECT #str1 = 'mmaa', #str2 = 'mama'
IF LEN(#str1) <> LEN(#str2)
BEGIN
SELECT 'NOT EQUAL'
END
ELSE
BEGIN
IF (SELECT COUNT(*) FROM
(
select substring(#str1, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str1) AND number > 0
UNION
select substring(#str2, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str2) AND number > 0
)
t)
= LEN(#str1)
SELECT '1 anagram'
ELSE
SELECT '0 not anagram'
END
But for words like mmaa and mama this program returns not anagram. But they are anagrams. How can I solve this problem?
rather crude, but how about:
Declare #S1 varChar(100) = 'mmaa'
Declare #S2 varChar(100) = 'mama'
Declare #c char(1)
Declare #i tinyint
Declare #o1 varChar(100) = ''
Declare #o2 varChar(100) = ''
While DataLength(#s1) > 0 Begin
Set #c = Left(#s1, 1)
Set #s1 = Substring(#s1, 2, len(#s1))
Set #i = 1
While #i <= Len(#o1) And #c > substring(#o1, #i, 1) Set #i += 1
Set #o1 = left(#o1, #i-1) + #c + substring(#o1, #i, len(#o1))
End
While DataLength(#s2) > 0 Begin
Set #c = Left(#s2, 1)
Set #s2 = Substring(#s2, 2, len(#s2))
Set #i = 1
While #i <= Len(#o2) And #c > substring(#o2, #i, 1) Set #i += 1
Set #o2 = left(#o2, #i-1) + #c + substring(#o2, #i, len(#o2))
End
Select case When #o1 = #o2 Then 'Anagram' Else 'Not Anagram' End
or to encapsulate the sort into a function,
Create FUNCTION [dbo].[SortString](#s varChar(8000))
RETURNS varChar(8000)
As
Begin
Declare #c char(1)
Declare #i int
Declare #out varChar(8000) = left(#s, 1)
While DataLength(#s) > 0 Begin
Set #s = Substring(#s, 2, len(#s)-1)
Set #c = Left(#s, 1)
Set #i = 0
While #i < Len(#out) And #c > substring(#out, #i+1, 1) Set #i += 1
Set #out = case when #i < Len(#out)
then stuff(#out, #i+1, 0, #c)
else #out + #c end
End
return #out
End
Please try using CHECKSUM_AGG
DECLARE #str1 VARCHAR(100), #str2 VARCHAR(100)
SELECT #str1 = 'mmaa', #str2 = 'mama'
IF LEN(#str1) <> LEN(#str2)
BEGIN
SELECT 'NOT EQUAL'
END
ELSE
BEGIN
IF(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM (select substring(#str1, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str1) AND number > 0)T1)=
(SELECT CHECKSUM_AGG(BINARY_CHECKSUM(*))
FROM (select substring(#str2, number, 1) as data
from master..spt_values as m
where m.type='p' and number <= len(#str2) AND number > 0)T2)
SELECT '1 anagram'
ELSE
SELECT '0 not anagram'
END

Stored Procedure returning an int

Hi i have the following stored proc in SQL Server 2005:
ALTER PROCEDURE [dbo].[slot_sp_EngineerTimeslots_Group]
#PROPREF VARCHAR(50),
#PRIORITYCODE VARCHAR(3),
#JOBLENGTH INT = 0,
#TIMESLOT VARCHAR(3)
AS
SET NOCOUNT ON
DECLARE #TOTALDAYS INT
DECLARE #TOTALDAYSTARGET INT
DECLARE #COUNTER INT
DECLARE #STARTTIME DATETIME
DECLARE #MIDDAYTIME DATETIME
DECLARE #ENDTIME DATETIME
DECLARE #STARTDATE DATETIME
DECLARE #iSTARTDATE DATETIME
DECLARE #CONTRACT VARCHAR(10)
SET #iSTARTDATE = GETDATE()
SET #STARTDATE = CONVERT(DATETIME,CONVERT(VARCHAR(10),#iSTARTDATE,120) + ' 00:00:00',120)
SELECT #CONTRACT = CONTRACT FROM [tbl_property] WHERE [PROPREF] = #PROPREF
-- Get the contract Start/MidDay/End times
Select
#STARTTIME = CONVERT(VARCHAR(10), #STARTDATE, 120) + ' ' + CONVERT(VARCHAR(5), ContractStartTime, 108),
#MIDDAYTIME = CONVERT(VARCHAR(10), #STARTDATE, 120) + ' ' + CONVERT(VARCHAR(5), ContractMiddayTime, 108),
#ENDTIME = CONVERT(VARCHAR(10), #STARTDATE, 120) + ' ' + CONVERT(VARCHAR(5), ContractEndTime, 108)
From
[tbl_contract]
WHERE
[tbl_contract].[CONTRACT]=#CONTRACT
-- Get Priority Times
Select
#TOTALDAYS =
CASE
WHEN ROUND(NEARCOMPLETEDURATION/24,0) < NEARCOMPLETEDURATION/24 THEN ROUND(NEARCOMPLETEDURATION/24,0) + 1
ELSE ROUND(NEARCOMPLETEDURATION/24,0)
END,
#TOTALDAYSTARGET =
CASE
WHEN ROUND(COMPLETEDURATION/24,0) < COMPLETEDURATION/24 THEN ROUND(COMPLETEDURATION/24,0) + 1
ELSE ROUND(COMPLETEDURATION/24,0)
END
FROM [ltbl_order_priority]
WHERE
[ltbl_order_priority].[CONTRACT] = #CONTRACT
AND [ltbl_order_priority].[PRIORITYCODE] = #PRIORITYCODE
-- Not sure what this is for yet butits going to be fun!
SET #COUNTER = 0
BEGIN
--Create Temp Table
CREATE TABLE
#TempEngineer
(
TempEngineer varchar(30),
BookedDate DateTime,
BookedFromTime DateTime,
BookedToTime DateTime,
TotalDays INT,
JobMins INT,
MinPMTime DateTime,
BTime DATETIME
)
While (#COUNTER <= #TOTALDAYS)
Begin
--Get details of active engineers from engineer table
INSERT #TempEngineer
SELECT
dbo.tbl_engineer.ENGINEER AS Engineer,
#STARTDATE AS StartDate,
CASE
WHEN ISNULL(dbo.tbl_engineer.STARTTIME,'') = '' THEN CONVERT(VARCHAR(10), #STARTDATE, 120) + ' ' + CONVERT(VARCHAR(5), #STARTTIME, 108)
ELSE CONVERT(VARCHAR(10), #STARTDATE, 120) + ' ' + CONVERT(VARCHAR(5), dbo.tbl_engineer.STARTTIME, 108)
END AS StartTime,
CASE
WHEN ISNULL( dbo.tbl_engineer.ENDTIME,'') = '' THEN CONVERT(VARCHAR(10), #STARTDATE, 120) + ' ' + CONVERT(VARCHAR(5), #ENDTIME, 108)
ELSE CONVERT(VARCHAR(10), #STARTDATE, 120) + ' ' + CONVERT(VARCHAR(5), dbo.tbl_engineer.ENDTIME, 108)
END AS EndTime,
#TOTALDAYS AS TotalDays,
NULL AS JobMins,
NULL AS MinPMTime,
NULL AS BTime
FROM dbo.tbl_engineer
WHERE dbo.tbl_engineer.ACTIVE = 1
AND Engineer NOT IN (SELECT Engineer
FROM slot_tbl_Schedule
WHERE bookedDate <= DATEADD(DAY, #TOTALDAYS, #STARTDATE)
AND bookedDate >= #STARTDATE)
--Get Details of Free time form schedule table
INSERT #TempEngineer
SELECT
slot_tbl_Schedule.Engineer AS Engineer,
slot_tbl_Schedule.BookedDate AS BookDate,
slot_tbl_Schedule.FromTime AS FromTime,
ISNULL(slot_tbl_Schedule.ToTime, CONVERT(VARCHAR(10), #STARTDATE, 120) + ' ' + CONVERT(VARCHAR(5), ENDTIME, 108)) AS ToTime,
#TOTALDAYS AS TotalDays,
NULL AS JobMins,
NULL AS MinPMTime,
NULL AS BTime
FROM
(
SELECT
Engineer,
BookedDate,
ToTime AS FromTime,
(SELECT MIN(fromTime) FROM slot_tbl_Schedule x WHERE x.engineer = s1.engineer AND x.bookedDate = s1.bookedDate AND x.fromTime >= s1.ToTime) AS ToTime
FROM slot_tbl_Schedule s1
WHERE CONVERT(DATETIME,CONVERT(VARCHAR(10),bookedDate,120),120) = #STARTDATE
UNION ALL
SELECT e2.Engineer, s2.BookedDate, CONVERT(VARCHAR(10), #STARTDATE, 120) + ' ' + CONVERT(VARCHAR(5), e2.StartTime, 114) AS FromTime, MIN(s2.FromTime) AS ToTime
FROM tbl_engineer e2 INNER JOIN slot_tbl_Schedule s2 ON s2.engineer = e2.engineer
WHERE CONVERT(DATETIME,CONVERT(VARCHAR(10),s2.bookedDate,120),120) = #STARTDATE
GROUP BY e2.Engineer, s2.BookedDate, e2.StartTime
HAVING MIN(s2.FromTime) > e2.StartTime
)
slot_tbl_Schedule INNER JOIN dbo.tbl_engineer engineer ON engineer.ENGINEER = slot_tbl_Schedule.Engineer
Select #COUNTER = #COUNTER + 1
Select #STARTDATE = DATEADD(Day, 1, #STARTDATE)
END -- While End
END -- Temp Table End
--Data from above select statements which is in the temp table
--
CREATE TABLE
#TempEngineerGroup
(
AppointmentType VARCHAR(50),
BookedDate DateTime,
BookedFromTime DateTime,
BookedToTime DateTime,
TotalDays INT,
JobMins INT
)
IF #TIMESLOT = 'AM'
INSERT INTO [#TempEngineerGroup]
SELECT 'FreeTime' AS [AppointmentType], BookedDate, BookedFromTime, BookedToTime, TotalDays, DATEDIFF(mi,BookedFromTime, BookedToTime) AS [JobMins]
FROM #TempEngineer
WHERE (DATEDIFF(mi,BookedFromTime, BookedToTime) >= #JOBLENGTH)
AND (DATEDIFF(mi,BookedFromTime, BookedToTime) < 600)
AND BookedFromTime < CONVERT(DATETIME,CONVERT(VARCHAR(10), BookedFromTime, 120) + ' ' + CONVERT(VARCHAR(5), #MIDDAYTIME, 114),120)
UNION
SELECT [slot_tbl_Schedule].[AppointmentType],[slot_tbl_Schedule].[BookedDate],[slot_tbl_Schedule].[FromTime],[slot_tbl_Schedule].[ToTime],0,[slot_tbl_Schedule].[JobMins]
FROM [slot_tbl_Schedule]
INNER JOIN [#TempEngineer] ON [slot_tbl_Schedule].[Engineer] = [#TempEngineer].[TempEngineer]
WHERE [slot_tbl_Schedule].[BookedDate] BETWEEN #iSTARTDATE AND DATEADD(dd,#TOTALDAYS,#iSTARTDATE)
ORDER BY BookedFromTime
IF #TIMESLOT = 'AT'
INSERT INTO [#TempEngineerGroup]
SELECT 'FreeTime' AS [AppointmentType], BookedDate, BookedFromTime, BookedToTime, TotalDays, DATEDIFF(mi,BookedFromTime, BookedToTime) AS JobMins
FROM #TempEngineer
WHERE (DATEDIFF(mi,BookedFromTime, BookedToTime) >= #JOBLENGTH)
AND (DATEDIFF(mi,BookedFromTime, BookedToTime) < 600)
UNION
SELECT [slot_tbl_Schedule].[AppointmentType], [slot_tbl_Schedule].[BookedDate],[slot_tbl_Schedule].[FromTime],[slot_tbl_Schedule].[ToTime],0,[slot_tbl_Schedule].[JobMins]
FROM [slot_tbl_Schedule]
INNER JOIN [#TempEngineer] ON [slot_tbl_Schedule].[Engineer] = [#TempEngineer].[TempEngineer]
WHERE [slot_tbl_Schedule].[BookedDate] BETWEEN #iSTARTDATE AND DATEADD(dd,#TOTALDAYS,#iSTARTDATE)
ORDER BY BookedFromTime
IF #TIMESLOT = 'PM'
INSERT INTO [#TempEngineerGroup]
SELECT 'FreeTime' AS [AppointmentType], BookedDate, BookedFromTime, BookedToTime, TotalDays, DATEDIFF(mi,BookedFromTime, BookedToTime) AS JobMins
FROM (
SELECT TempEngineer, BookedDate, BookedFromTime AS BTime, BookedToTime, TotalDays, JobMins, MinPMTime,
CASE
WHEN BookedFromTime >= CONVERT(DATETIME,CONVERT(VARCHAR(10), BookedFromTime, 120) + ' ' + CONVERT(VARCHAR(5), #MIDDAYTIME, 114),120) Then BookedFromTime
WHEN BookedFromTime < CONVERT(DATETIME,CONVERT(VARCHAR(10), BookedFromTime, 120) + ' ' + CONVERT(VARCHAR(5), #MIDDAYTIME, 114),120) Then MinPMTime
END AS BookedFromTime
FROM (
SELECT TempEngineer, BookedDate, BookedFromTime, BookedToTime, TotalDays, DATEDIFF(mi,BookedFromTime, BookedToTime) AS JobMins,
max(CASE WHEN BookedFromTime < CONVERT(DATETIME,CONVERT(VARCHAR(10), BookedFromTime, 120) + ' ' + CONVERT(VARCHAR(5), #MIDDAYTIME, 114),120) AND IsNull(PMAppointments, 0) >= 0 THEN CONVERT(DATETIME,CONVERT(VARCHAR(10), BookedFromTime, 120) + ' ' + CONVERT(VARCHAR(5), #MIDDAYTIME, 114),120)
WHEN BookedFromTime > CONVERT(DATETIME,CONVERT(VARCHAR(10), BookedFromTime, 120) + ' ' + CONVERT(VARCHAR(5), #MIDDAYTIME, 114),120) AND IsNull(PMAppointments, 0) >= 0 THEN BookedFromTime END) AS MinPMTime
FROM (
SELECT TempEngineer, BookedDate, BookedFromTime, BookedToTime, TotalDays, DATEDIFF(mi,BookedFromTime, BookedToTime) AS JobMins,
CASE
WHEN convert(datetime,convert(varchar(5),BookedFromTime,108),120) >= convert(datetime,convert(varchar(5),#ENDTIME,108),120) THEN DATEDIFF(mi,convert(datetime,convert(varchar(5),BookedFromTime,108),120), convert(datetime,convert(varchar(5),#ENDTIME,108),120))/#JOBLENGTH
WHEN convert(datetime,convert(varchar(5),BookedToTime,108),120) >= convert(datetime,convert(varchar(5),#MIDDAYTIME,108),120) THEN DATEDIFF(mi,convert(datetime,convert(varchar(5),#MIDDAYTIME,108),120), convert(datetime,convert(varchar(5),BookedToTime,108),120))/#JOBLENGTH
END As PMAppointments
FROM #TempEngineer
)INSIDEQUERY_A
GROUP BY TempEngineer, BookedDate, BookedFromTime, BookedToTime, TotalDays, JobMins
)INSIDEQUERY_B
GROUP BY TempEngineer, BookedDate, BookedFromTime, BookedToTime, TotalDays, JobMins, MinPMTime
)OUTSIDEQUERY
WHERE (DATEDIFF(mi,BookedFromTime, BookedToTime) >= #JOBLENGTH)
AND (DATEDIFF(mi,BookedFromTime, BookedToTime) < 600)
GROUP BY TempEngineer, BookedDate, BookedFromTime, BookedToTime, TotalDays, JobMins, MinPMTime
UNION
SELECT [slot_tbl_Schedule].[AppointmentType], [slot_tbl_Schedule].[BookedDate],[slot_tbl_Schedule].[FromTime],[slot_tbl_Schedule].[ToTime],0,[slot_tbl_Schedule].[JobMins]
FROM [slot_tbl_Schedule]
INNER JOIN [#TempEngineer] ON [slot_tbl_Schedule].[Engineer] = [#TempEngineer].[TempEngineer]
WHERE [slot_tbl_Schedule].[BookedDate] BETWEEN #iSTARTDATE AND DATEADD(dd,#TOTALDAYS,#iSTARTDATE)
ORDER BY BookedFromTime
DECLARE #C1_AppointmentType VARCHAR(50)
DECLARE #C1_BookedDate DateTime
DECLARE #C1_BookedFromTime DateTime
DECLARE #C1_BookedToTime DateTime
DECLARE #C1_TotalDays INT
DECLARE #C1_JobMins INT
DECLARE #WC_AppointmentType VARCHAR(50)
DECLARE #WC_BookedDate DateTime
DECLARE #WC_BookedFromTime DateTime
DECLARE #WC_BookedToTime DateTime
DECLARE #WC_TotalDays INT
DECLARE #WC_JobMins INT
DECLARE #Saved AS BIT
CREATE TABLE
#TempEngineerGroupMain
(
AppointmentType VARCHAR(50),
BookedDate DateTime,
BookedFromTime DateTime,
BookedToTime DateTime,
TotalDays INT,
JobMins INT
)
DECLARE c1 CURSOR READ_ONLY
FOR
SELECT *
FROM [#TempEngineerGroup]
ORDER BY [BookedDate] ASC, [AppointmentType] ASC, BookedFromTime ASC, [JobMins] desc
OPEN c1
FETCH NEXT FROM c1 INTO #C1_AppointmentType, #C1_BookedDate, #C1_BookedFromTime, #C1_BookedToTime, #C1_TotalDays, #C1_JobMins
SET #Saved = 0
WHILE ##FETCH_STATUS = 0
BEGIN
IF ISNULL(#WC_AppointmentType,'') = ''
BEGIN
SET #WC_AppointmentType = #C1_AppointmentType
SET #WC_BookedDate = #C1_BookedDate
SET #WC_BookedFromTime = #C1_BookedFromTime
SET #WC_BookedToTime = #C1_BookedToTime
SET #WC_TotalDays = #C1_TotalDays
SET #WC_JobMins = #C1_JobMins
END
ELSE -- Start Checks
BEGIN
IF #C1_BookedDate != #WC_BookedDate -- Different Date
BEGIN
INSERT INTO [#TempEngineerGroupMain] ([AppointmentType],[BookedDate],[BookedFromTime],[BookedToTime],[TotalDays],[JobMins])
VALUES ( #WC_AppointmentType, #WC_BookedDate, #WC_BookedFromTime, #WC_BookedToTime, #WC_TotalDays, DATEDIFF(mi,#WC_BookedFromTime,#WC_BookedToTime))
SET #WC_AppointmentType = #C1_AppointmentType
SET #WC_BookedDate = #C1_BookedDate
SET #WC_BookedFromTime = #C1_BookedFromTime
SET #WC_BookedToTime = #C1_BookedToTime
SET #WC_TotalDays = #C1_TotalDays
SET #WC_JobMins = #C1_JobMins
SET #Saved = 0
END
IF #C1_AppointmentType != #WC_AppointmentType -- Different Appointment so Store Value
BEGIN
INSERT INTO [#TempEngineerGroupMain] ([AppointmentType],[BookedDate],[BookedFromTime],[BookedToTime],[TotalDays],[JobMins])
VALUES ( #WC_AppointmentType, #WC_BookedDate, #WC_BookedFromTime, #WC_BookedToTime, #WC_TotalDays, DATEDIFF(mi,#WC_BookedFromTime,#WC_BookedToTime))
SET #WC_AppointmentType = #C1_AppointmentType
SET #WC_BookedDate = #C1_BookedDate
SET #WC_BookedFromTime = #C1_BookedFromTime
SET #WC_BookedToTime = #C1_BookedToTime
SET #WC_TotalDays = #C1_TotalDays
SET #WC_JobMins = #C1_JobMins
SET #Saved = 0
END
ELSE IF #C1_BookedDate = #WC_BookedDate AND #C1_AppointmentType = #WC_AppointmentType AND #C1_BookedFromTime <= #WC_BookedFromTime AND #C1_BookedToTime >= #WC_BookedFromTime
BEGIN -- Change Start Time
SET #WC_BookedFromTime = #C1_BookedFromTime
SET #Saved = 0
END
ELSE IF #C1_BookedDate = #WC_BookedDate AND #C1_AppointmentType = #WC_AppointmentType AND #C1_BookedFromTime <= #WC_BookedToTime AND #C1_BookedToTime >= #WC_BookedFromTime
BEGIN -- Change End Time
SET #WC_BookedToTime = #C1_BookedToTime
SET #Saved = 0
END
ELSE IF #C1_BookedDate = #WC_BookedDate AND #C1_AppointmentType = #WC_AppointmentType AND #C1_BookedFromTime < #WC_BookedFromTime AND #C1_BookedToTime < #WC_BookedFromTime
BEGIN -- New
INSERT INTO [#TempEngineerGroupMain] ([AppointmentType],[BookedDate],[BookedFromTime],[BookedToTime],[TotalDays],[JobMins])
VALUES ( #WC_AppointmentType, #WC_BookedDate, #WC_BookedFromTime, #WC_BookedToTime, #WC_TotalDays, DATEDIFF(mi,#WC_BookedFromTime,#WC_BookedToTime))
SET #WC_AppointmentType = #C1_AppointmentType
SET #WC_BookedDate = #C1_BookedDate
SET #WC_BookedFromTime = #C1_BookedFromTime
SET #WC_BookedToTime = #C1_BookedToTime
SET #WC_TotalDays = #C1_TotalDays
SET #WC_JobMins = #C1_JobMins
SET #Saved = 1
END
ELSE IF #C1_BookedDate = #WC_BookedDate AND #C1_AppointmentType = #WC_AppointmentType AND #C1_BookedFromTime > #WC_BookedToTime
BEGIN -- New
INSERT INTO [#TempEngineerGroupMain] ([AppointmentType],[BookedDate],[BookedFromTime],[BookedToTime],[TotalDays],[JobMins])
VALUES ( #WC_AppointmentType, #WC_BookedDate, #WC_BookedFromTime, #WC_BookedToTime, #WC_TotalDays, DATEDIFF(mi,#WC_BookedFromTime,#WC_BookedToTime))
SET #WC_AppointmentType = #C1_AppointmentType
SET #WC_BookedDate = #C1_BookedDate
SET #WC_BookedFromTime = #C1_BookedFromTime
SET #WC_BookedToTime = #C1_BookedToTime
SET #WC_TotalDays = #C1_TotalDays
SET #WC_JobMins = #C1_JobMins
SET #Saved = 1
END
END
FETCH NEXT FROM c1 INTO #C1_AppointmentType, #C1_BookedDate, #C1_BookedFromTime, #C1_BookedToTime, #C1_TotalDays, #C1_JobMins
END
IF #Saved = 0
INSERT INTO [#TempEngineerGroupMain] ([AppointmentType],[BookedDate],[BookedFromTime],[BookedToTime],[TotalDays],[JobMins])
VALUES ( #WC_AppointmentType, #WC_BookedDate, #WC_BookedFromTime, #WC_BookedToTime, #WC_TotalDays, DATEDIFF(mi,#WC_BookedFromTime,#WC_BookedToTime))
CLOSE c1
DEALLOCATE c1
SELECT *
FROM [#TempEngineerGroupMain]
thr problem is that while it is supposed to return rows of from the temp table in linq it returns an int is there any reason as to why this would happen?
One common reason is that stored procedures have notoriously weak metadata, particularly for complex code with branches etc. It is very hard for the external code to really understand what is being selected/returned.
A common trick is to replace the sproc with something mind-numbingly simple (i.e. that simply returns any sample data of the desired schema) for the process of inspection, and then swap back to the real code. Alternatively, if possible consider swapping to a UDF - as UDFs have much stronger schema metadata.
Of course, you could also hand-edit the DBML based on something similar that works correctly.
As an aside - you may have a number of issues with that existing code, including (but not limited to) DML/DDL transitions (forces recompile), multiple updates to the same table (forces selective recompile) - not to mention the cursor usage (which may of may not be necessary). Table variables (#table rather than #table) may be useful too. I'm not offering to re-write it; just note some things you might want to look at.
The first SELECT in your SPROC is yielding an INT into the temporary variable
SELECT #CONTRACT = CONTRACT FROM [tbl_property] WHERE [PROPREF] = #PROPREF
which is what is tripping up the metadata. You should do a
SET #CONTRACT = (SELECT CONTRACT FROM [tbl_property] WHERE [PROPREF] = #PROPREF)
instead.