Stored Procedure returning an int - sql
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.
Related
Create a existing SQL table valued function to Oracle
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
Operand type clash: date is incompatible with int when trying to use dynamic Sql
I have created a sql statement which uses variables for the start and end dates and this works declare #startDate varchar(20) = '2022-06-01' declare #endDate varchar(20) = '2022-06-29' select distinct instanceId as [JourneyID], CAST((select case when ISDATE(questionComment) = 1 THEN CAST(questionComment as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 170346 and instanceId = qanda.instanceId ) as varchar) as [AuditDate] ,CAST((select case when ISDATE(UpdateDate) = 1 THEN CAST(UpdateDate as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 176537 and instanceId = qanda.instanceId) as varchar) as [UpdatedDate] from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] qanda where (select case when ISDATE(questionComment) = 1 THEN CAST(questionComment as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 170346 and instanceId = qanda.instanceId ) >= CAST(#startDate as date) and (select case when ISDATE(questionComment) = 1 THEN CAST(questionComment as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 170346 and instanceId = qanda.instanceId ) <= CAST(#endDate as date) and UpdateDate is not null I am trying to run this using dynamic SQL as I need to pass in server and database name dynamically as this query is used from an SSRS report. I get a Operand type clash: date is incompatible with int This is my dynamic SQL #startDate varchar(15), #endDate varchar(15), set #OPENQUERY = 'Select [JourneyID], [AuditDate], [UpdatedDate] from OPENQUERY(' + #ServerName + ',''' set #sql = 'Select distinct instanceId as [JourneyID], CAST((select case when ISDATE(questionComment) = 1 THEN CAST(questionComment as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 170346 and instanceId = qanda.instanceId ) as varchar) as [AuditDate] ,CAST((select case when ISDATE(UpdateDate) = 1 THEN CAST(UpdateDate as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 176537 and instanceId = qanda.instanceId) as varchar) as [UpdatedDate] from ' + #DatabaseName + '.dbo.AB_SurveyQandA qanda where (select case when ISDATE(questionComment) = 1 THEN CAST(questionComment as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 170346 and instanceId = qanda.instanceId ) >= ' + CAST(#startDate as nvarchar) + ' and (select case when ISDATE(questionComment) = 1 THEN CAST(questionComment as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 170346 and instanceId = qanda.instanceId ) <= ' + CAST(#endDate as nvarchar) + ' and UpdateDate is not null '')' I have tried casting #startDate and #endDate as date but then it says date is incompatible with operand + What do I need to do to be able to get this to work in a dynamic SQL string?
As Per Ed Bangga suggestion here is the result of the SQL print here is the result of the print SQL Select [JourneyID], [AuditDate], [UpdatedDate] from OPENQUERY(MYSTERYDB,'Select distinct instanceId as [JourneyID], CAST((select case when ISDATE(questionComment) = 1 THEN CAST(questionComment as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 170346 and instanceId = qanda.instanceId ) as varchar) as [AuditDate] ,CAST((select case when ISDATE(UpdateDate) = 1 THEN CAST(UpdateDate as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 176537 and instanceId = qanda.instanceId) as varchar) as [UpdatedDate] from AbellioWMTData_April_21.dbo.AB_SurveyQandA qanda where (select case when ISDATE(questionComment) = 1 THEN CAST(questionComment as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 170346 and instanceId = qanda.instanceId ) >= '2022-06-01' and (select case when ISDATE(questionComment) = 1 THEN CAST(questionComment as date) END from [AbellioWMTData_April_21].[dbo].[AB_SurveyQandA] where protoQuestionId = 170346 and instanceId = qanda.instanceId ) <= '2022-06-29' and UpdateDate is not null ')
Get Current date, current month, current year depending on user selection - SQL stored procedure
I have a stored procedure that gives results depending on multiple values from the User(filtering), in my query I have 2 date columns date_start and date_end, I want to allow the user to return data depending on his selection from 2dropdownmenu one for start date and the other for end date as this: (this day - this month - this year - All Data). I'm working Using C# winform, all the search part is done and it's working, but I can't figure out how to add the query to the filter depending on the value coming from the dropdownmenu. current date : where date_start= cast(getdate() as Date) current month: WHERE MONTH(date_start) = MONTH(CURRENT_DATE()) AND YEAR(date_start) = YEAR(CURRENT_DATE()) current year: where year(date_start) = year(getdate()) and datepart(dy, date_start) <= datepart(dy, getdate()) here is my stored producer: ALTER procedure [dbo].[ContractsSearch] ( #cust_id nvarchar (10) = NULL, #name nvarchar (50) = NULL, #shop_id nvarchar (10) = NULL, #duration nvarchar (3) = NULL, #usage nvarchar (20) = NULL, #rent_type nvarchar (20) = NULL, #date_start nvarchar (20)= NULL, #date_end nvarchar (20)= NULL, #archive bit=NULL ) AS BEGIN SET NOCOUNT ON; SELECT dbo.contracts.ID, dbo.contracts.cust_id, dbo.customers.name, dbo.contracts.shop_id, dbo.contracts.duration, dbo.contracts.price, dbo.contracts.tax, dbo.contracts.usage, dbo.contracts.rent_type, dbo.contracts.price2, dbo.contracts.note2, dbo.contracts.date_start, dbo.contracts.date_end, dbo.contracts.note, dbo.contracts.app_user FROM dbo.customers INNER JOIN dbo.contracts ON dbo.customers.cust_id = dbo.contracts.cust_id WHERE (contracts.cust_id LIKE N'%' + #cust_id + '%' OR #cust_id IS NULL) AND (customers.name LIKE N'%' + #name + '%' OR #name IS NULL) AND (contracts.shop_id = #shop_id OR #shop_id='' OR #shop_id IS NULL) AND (contracts.duration= #duration OR #duration='' OR #duration IS NULL) AND (contracts.usage = #usage OR #usage=N'إختر نوع الإستعمال' OR #usage IS NULL) AND (contracts.rent_type = #rent_type OR #rent_type=N'إختر نوع الايحار' OR #rent_type IS NULL) AND (contracts.archive = #archive OR #archive IS NULL) END
With the help of comments, and especially from #Charlieface I created the Procedure, Thank you all. Here is the final procedure, and I welcome any improvements suggestions: ALTER procedure [dbo].[ContractsSearch] ( #cust_id nvarchar (10) = NULL, #name nvarchar (50) = NULL, #shop_id nvarchar (10) = NULL, #duration nvarchar (3) = NULL, #usage nvarchar (20) = NULL, #rent_type nvarchar (20) = NULL, #date_start nvarchar (20) = NULL, #date_end nvarchar (20) = NULL, #archive bit=NULL ) AS BEGIN SET NOCOUNT ON; DECLARE #StartDate1 as date = NULL DECLARE #StartDate2 as date = NULL if #date_start = N'اليوم الحالي' BEGIN set #StartDate1 = DATEADD(DAY, 0, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP)) set #StartDate2 = DATEADD(DAY, 1, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP)) END ELSE if #date_start = N'الشهر الحالي' BEGIN set #StartDate1 = dateadd(m, datediff(m, 0, GetDate()), 0) set #StartDate2 = dateadd(m, datediff(m, -1, GetDate()), 0) END ELSE if #date_start = N'السنة الحالية' BEGIN set #StartDate1 = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) set #StartDate2 = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) + 1, -1) END DECLARE #EndDate1 as date = NULL DECLARE #EndDate2 as date = NULL if #date_end = N'اليوم الحالي' BEGIN set #EndDate1 = DATEADD(DAY, 0, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP)) set #EndDate2 = DATEADD(DAY, 1, DATEDIFF(DAY, 0, CURRENT_TIMESTAMP)) END ELSE if #date_end = N'الشهر الحالي' BEGIN set #EndDate1 = dateadd(m, datediff(m, 0, GetDate()), 0) set #EndDate2 = dateadd(m, datediff(m, -1, GetDate()), 0) END ELSE if #date_end = N'السنة الحالية' BEGIN set #EndDate1 = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) set #EndDate2 = DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) + 1, -1) END DECLARE #sql nvarchar(max) = N' SELECT dbo.contracts.ID, dbo.contracts.cust_id, dbo.customers.name, dbo.contracts.shop_id, dbo.contracts.duration, dbo.contracts.price, dbo.contracts.tax, dbo.contracts.usage, dbo.contracts.rent_type, dbo.contracts.price2, dbo.contracts.note2, dbo.contracts.date_start, dbo.contracts.date_end, dbo.contracts.note, dbo.contracts.app_user FROM dbo.customers INNER JOIN dbo.contracts ON dbo.customers.cust_id = dbo.contracts.cust_id WHERE 1 = 1' + CASE WHEN #cust_id !=NULL THEN N' AND contracts.cust_id LIKE char(37) + #cust_id + char(37)' ELSE N'' END + CASE WHEN #name !=NULL THEN N' AND customers.name LIKE char(37) + #name + char(37) ' ELSE N'' END + CASE WHEN #shop_id !=NULL THEN N' AND contracts.shop_id = #shop_id' ELSE N'' END + CASE WHEN #duration !=NULL THEN N' AND contracts.duration= #duration' ELSE N'' END + CASE WHEN #usage !=NULL OR #usage != N'إختر نوع الإستعمال' THEN N' AND contracts.usage = #usage' ELSE N'' END + CASE WHEN #rent_type !=NULL OR #rent_type!= N'إختر نوع الايحار' THEN N' AND contracts.rent_type = #rent_type' ELSE N'' END + CASE WHEN #date_start !=NULL OR #date_start != N'تاريخ البدء'THEN N' AND contracts.date_start >= #StartDate1 and contracts.date_start < #StartDate2' ELSE N'' END + CASE WHEN #date_end !=NULL OR #date_end !=N'تاريخ الإنتهاء' THEN N' AND contracts.date_end >= #EndDate1 and contracts.date_end < #EndDate2' ELSE N'' END + CASE WHEN #archive !=NULL THEN N' AND contracts.archive = #archive' ELSE N'' END; DECLARE #params nvarchar(max) = N' #cust_id nvarchar (10), #name nvarchar (50), #shop_id nvarchar (10), #duration nvarchar (3), #usage nvarchar (20), #rent_type nvarchar (20), #StartDate1 date, #StartDate2 date, #EndDate1 date, #EndDate2 date, #archive bit'; --PRINT #sql; EXEC sys.sp_executesql #sql, #params, #cust_id, #name, #shop_id, #duration, #usage, #rent_type, #StartDate1, #StartDate2, #EndDate1, #EndDate2 , #archive; END
Get value from table while executing SP
I have several stored procedures that run daily/weekly/monthly that email resultset in HTML format. I declare a value on each of them as a "Goal" to divide by. This works great but it is very time consuming when we need to change the value of each "Goal". I want to store all the values in a table and have the SP call on that table to get value of "Goal". I am showing one of the SPs for an example and will also show the table i have created as GoalSetUp DECLARE #Offset INT , #Start DATETIME , #End DATETIME , #VC CHAR(2) , #ap CHAR(2) ,#Goal VARCHAR(10) --------------------------------------------------- SET #VC = 'VC' SET #ap = 'ap'SET #Goal= '15' SET #Offset = 1 SET #Start = dateadd(day, datediff(day, 0, getdate()), -#Offset) SET #End = dateadd(day, datediff(day, 0, getdate()), -#Offset) --VC AP-- DECLARE #23 varchar(max) DECLARE #Head23 varchar(max) DECLARE #Tail23 varchar(max) DECLARE #mailitem_id23 as int DECLARE #statusMsg23 as varchar(max)DECLARE #Error23 as varchar(max) DECLARE #Note23 as varchar(max) SET NoCount On; SET #mailitem_id23 = null SET #statusMsg23 = null SET #Error23 = null SET #Note23 = null SET #Tail23 = '</table></body></html>'; SET #Head23 = '<html><head>' + '<style>' + 'td {border: solid black 1px;padding-left:5px;padding-right:5px;padding-top:1px;padding-bottom:1px;font-size:9pt;color:Black;} ' + '</style>' + '</head>' + '<body><table cellpadding=0 cellspacing=0 border=0 width=100%>' + '<tr bgcolor=#808080>'+ '<td width=5%><b>Codes</b></td>'+'<td width=5%><b>TimeSUM</b></td>'+'<td width=5%><b>Units</b></td>'+'<td width=5%><b>UPH</b></td>'+'<td width=5%><b>Goal%</b></td>'+'<td width=5%><b>ID</b></td>'+'<td width=10%><b>Associate Name</b></td></tr>'; SELECT #23= (SELECT [TD] = (t.DeptCode + '-' + t.OpCode) ,[TD] = right(convert(varchar(9),(sum(datediff(second,StartTime,FinishTime)) / 3600 )),3) + ':' + right('0' + convert(varchar(2),(sum(datediff(second,StartTime,FinishTime)) / 60) % 60 ),2) ,[TD] = PARSENAME(convert(varchar,cast(sum(units) as money),1),2) ,[TD] = cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60 as decimal(10,0)) ,[TD] = isnull((convert(varchar(30),cast((isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60)/nullif(#Goal,0)*100 as decimal(10,0))) + '%'), ' ') ,[TD] = t.ID ,[TD] = UPPER(isnull(ai.FirstName + ' ','**********fix me') + isnull(ai.LastName,'')) FROM TimeLog t left join AssociateInfo ai on t.Id = ai.Id where t.EventDate >= #Start and t.EventDate <= #End and t.DeptCode = #VC and t.OpCode = #ap group by t.EventDate, t.id, t.DeptCode, t.OpCode, ai.FirstName, ai.LastName ORDER BY cast(isnull(sum(Units) / nullif(sum(datediff(minute,StartTime,FinishTime))*1.0,0),0.0)*60 as decimal(10,0)) desc FOR XML RAW('tr'), ELEMENTS) SET #23 = REPLACE(#23, '_x0020_', SPACE(1))SET #23 = REPLACE(#23, '_x003D_', '=')SET #23 = REPLACE(#23, '<tr><TRRow>1</TRRow>', '<tr bgcolor=#C6CFFF>')SET #23 = REPLACE(#23, '<TRRow>0</TRRow>', '')SET #23 = #Head23 + #23 + #Tail23 Select #23 ----------------------------------------------------------------- ----------------------------------------------------------------- --Email DECLARE #Body VARCHAR(MAX) SET #Body = ISNULL(#23, ' ') EXEC msdb.dbo.sp_send_dbmail #profile_name ='myprofile', #recipients = 'myemail#myemail.com', #subject = 'Email', #body = #Body, #body_format = 'HTML' GoalSetUp table DeptCode OpCode Goal Location VC ap 15 10 Is there a way i can call on GoalSetUp table to retreive the value of Goal For #Goal value used in my SP?
SET #Goal= (select Goal from GoalSetUp where /*conditions returning one row here*/)
You must edit your stored procedures in order to take a dynamic value for #Goal. Something like this DECLARE #Offset INT , #Start DATETIME , #End DATETIME , #VC CHAR(2) , #ap CHAR(2) , #Goal VARCHAR(10) --------------------------------------------------- SET #VC = 'VC' SET #ap = 'ap' SELECT #Goal= GOAL FROM GOALTable --change this row SET #Offset = 1 SET #Start = dateadd(day, datediff(day, 0, getdate()), -#Offset) SET #End = dateadd(day, datediff(day, 0, getdate()), -#Offset)
Calculate Duration between two dates (Month and Year will be Considered)
I have two dates 06-Jan-2009 and 12-Dec-2010 I want to calculate the date difference between these two dates.. (basis on the month and year). I want to get the answer 2 Year. But if dates is 06-Jan-2009 And 12-Oct-2010 then I need 10 Months as output.
Try this one: Declare #SDate DateTime ='06-Jan-2009' Declare #EDate DateTime ='12-Oct-2009' select case when DateDiff(M,#sDate,#EDate) <=12 then DateDiff(M,#sDate,#EDate) else Round( ( Convert(Decimal(18,0) ,DateDiff(M,#sDate,#EDate)/12.0)),0) end
declare #Birthdate datetime declare #AsOnDate datetime declare #years int declare #months int declare #days int declare #hours int declare #minutes int --NOTE: date of birth must be smaller than As on date, --else it could produce wrong results set #Birthdate = '1989-11-30 9:27 pm' --birthdate set #AsOnDate = Getdate() --current datetime --calculate years select #years = datediff(year,#Birthdate,#AsOnDate) --calculate months if it's value is negative then it --indicates after __ months; __ years will be complete --To resolve this, we have taken a flag #MonthOverflow... declare #monthOverflow int select #monthOverflow = case when datediff(month,#Birthdate,#AsOnDate) - ( datediff(year,#Birthdate,#AsOnDate) * 12) <0 then -1 else 1 end --decrease year by 1 if months are Overflowed select #Years = case when #monthOverflow < 0 then #years-1 else #years end select #months = datediff(month,#Birthdate,#AsOnDate) - (#years * 12) --as we do for month overflow criteria for days and hours --& minutes logic will followed same way declare #LastdayOfMonth int select #LastdayOfMonth = datepart(d,DATEADD (s,-1,DATEADD(mm, DATEDIFF(m,0,#AsOnDate)+1,0))) select #days = case when #monthOverflow<0 and DAY(#Birthdate)> DAY(#AsOnDate) then #LastdayOfMonth + (datepart(d,#AsOnDate) - datepart(d,#Birthdate) ) - 1 else datepart(d,#AsOnDate) - datepart(d,#Birthdate) end declare #hoursOverflow int select #hoursOverflow = case when datepart(hh,#AsOnDate) - datepart(hh,#Birthdate) <0 then -1 else 1 end select #hours = case when #hoursOverflow<0 then 24 + datepart(hh,#AsOnDate) - datepart(hh,#Birthdate) else datepart(hh,#AsOnDate) - datepart(hh,#Birthdate) end declare #minutesOverflow int select #minutesOverflow = case when datepart(mi,#AsOnDate) - datepart(mi,#Birthdate) <0 then -1 else 1 end select #minutes = case when #hoursOverflow<0 then 60 - (datepart(mi,#AsOnDate) - datepart(mi,#Birthdate)) else abs(datepart (mi,#AsOnDate) - datepart(mi,#Birthdate)) end select #Months=case when #days < 0 or DAY(#Birthdate)> DAY(#AsOnDate) then #Months-1 else #Months end Declare #lastdayAsOnDate int; set #lastdayAsOnDate = datepart(d,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#AsOnDate),0))); Declare #lastdayBirthdate int; set #lastdayBirthdate = datepart(d,DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,#Birthdate)+1,0))); if (#Days < 0) ( select #Days = case when( #lastdayBirthdate > #lastdayAsOnDate) then #lastdayBirthdate + #Days else #lastdayAsOnDate + #Days end ) print convert(varchar,#years) + ' year(s), ' + convert(varchar,#months) + ' month(s), ' + convert(varchar,#days) + ' day(s), ' + convert(varchar,#hours) + ':' + convert(varchar,#minutes) + ' hour(s)'
Please tried with below query Declare #SDate DateTime ='01-Jan-2009' Declare #EDate DateTime ='12-Oct-2009' SET #EDate = DATEADD(M, 1, #EDate) select DateDiff(M,#sDate,#EDate)
select Round( ( Convert(Decimal(18,2),DateDiff(M,'06-Jan-2009','12-Dec-2010')/12.0)),0) as Years
I think that would be work for me: DECLARE #start DATETIME='01-Jan-2008' DECLARE #end DATETIME='10-Nov-2011' DECLARE #duration INT --SELECT #start = '2011-10-10', #end = '2013-10-10' --select DATEPART(dd,#start) SET #Start = Dateadd(DAY, -( Datepart(DD, #Start) - 1 ), #Start) SET #end = Dateadd(DAY, -( Datepart(day, #end) - 1 ), #end) SET #end = Dateadd(day, Day(Dateadd(mm, Datediff(mm, -1, #end), -1)), #end) SELECT #duration = Datediff(mm, #Start, #end) SELECT CASE WHEN #duration = 0 THEN NULL WHEN #duration%12 = 0 THEN( CONVERT(NVARCHAR, #duration / 12) + ' Year ' ) WHEN #duration > 12 THEN( CONVERT(NVARCHAR, #duration / 12) + ' Year ' + CONVERT(NVARCHAR, #duration % 12) + ' Month ' ) ELSE (SELECT CONVERT(NVARCHAR, #duration % 12) + ' Month') END
declare #Birthdate datetime declare #AsOnDate datetime declare #years varchar(4) declare #months varchar(3) declare #days varchar(3) declare #hours varchar(3) declare #minutes varchar(2) set #Birthdate = '1989-11-30 9:27 AM' --birthdate set #AsOnDate = getdate() --current datetime select #years = datediff(year,#Birthdate,#AsOnDate) select #months = datediff(month,#Birthdate,#AsOnDate) - ( datediff(year,#Birthdate,#AsOnDate) * 12) select #days = datepart(d,#AsOnDate) - datepart(d,#Birthdate) select #hours = datepart(hh,#AsOnDate) - datepart(hh,#Birthdate) select #minutes = abs(datepart(mi,#AsOnDate) - datepart(mi,#Birthdate)) print #years + ' year(s), ' + #months + ' month(s), ' + #days + ' day(s), ' + #hours + ':' + #minutes + ' hour(s)' OUT PUT: