I want to create a stored procedure in SQL Server 2012 that returns a temp table.
My code is
CREATE PROC [dbo].[aac_trial_balance_data]
#company_code char(5),
#target_level int,
#StartDate char(12),
#EndDate char(12)
AS
BEGIN
SELECT
dbo.getParentCode(chart_code,#target_level,LEVEL) chart_code,
level,
SUM(debit) debit,
SUM(credit) credit
FROM
acc_trial_balance_vw
WHERE
convert(datetime, create_date, 103) between convert(datetime, cast(#StartDate as datetime), 103)
and convert(datetime, cast(#EndDate as datetime) + '23:59:59', 103)
AND company_code = #company_code
GROUP BY
chart_code, LEVEL
END
I want to create a Temp table after the query like
CREATE PROC [dbo].[aac_trial_balance_data]
#company_code char(5),
#target_level int,
#StartDate char(12),
#EndDate char(12)
AS
BEGIN
(select
dbo.getParentCode(chart_code,#target_level,LEVEL) chart_code,
level,
SUM(debit) debit,
SUM(credit) credit
from acc_trial_balance_vw
where
convert(datetime,create_date,103) between convert(datetime, cast(#StartDate as datetime) , 103)
and convert(datetime, cast(#EndDate as datetime)+'23:59:59' , 103)
and company_code = #company_code
GROUP BY chart_code, LEVEL
)
AS
#TEMP-TABLE -- This is my Temp Table That i want to create
END
How can id do it
you can create temp table, just use
If Object_Id('Tempdb..#temp') Is Not Null
Drop Table #temp1
create table #temp(your columns)
Insert into #temp select...
or use select into #temp like
select
dbo.getParentCode(chart_code,#target_level,LEVEL) chart_code,
level,
SUM(debit) debit,
SUM(credit) credit into #tempTable
from acc_trial_balance_vw
where
convert(datetime,create_date,103) between convert(datetime, cast(#StartDate as datetime) , 103)
and convert(datetime, cast(#EndDate as datetime)+'23:59:59' , 103)
and company_code = #company_code
GROUP BY chart_code, LEVEL
try this:
(select
dbo.getParentCode(chart_code,#target_level,LEVEL) chart_code,
level,
SUM(debit) debit,
SUM(credit) credit
INTO #THIS_TEMP_TABLE
from acc_trial_balance_vw
where
convert(datetime,create_date,103) between convert(datetime, cast(#StartDate as datetime) , 103)
and convert(datetime, cast(#EndDate as datetime)+'23:59:59' , 103)
and company_code = #company_code
GROUP BY chart_code, LEVEL)
SELECT * FROM #THIS_TEMP_TABLE
Drop table #THIS_TEMP_TABLE
Try inserting into #temptable after your dbname from acc_trial_balance_vw
CREATE PROC [dbo].[aac_trial_balance_data]
#company_code char(5),
#target_level int,
#StartDate char(12),
#EndDate char(12)
AS
BEGIN
(select
dbo.getParentCode(chart_code,#target_level,LEVEL) chart_code,
level,
SUM(debit) debit,
SUM(credit) credit
into #TEMPTABLE -->>> Inserting here
from acc_trial_balance_vw
where
convert(datetime,create_date,103) between convert(datetime, cast(#StartDate as datetime) , 103)
and convert(datetime, cast(#EndDate as datetime)+'23:59:59' , 103)
and company_code = #company_code
GROUP BY chart_code, LEVEL
)
AS
END
create table #temp(company_code char(5),target_level int,StartDate char(12))
insert into #temp('','','')
select * from #temp
select
dbo.getParentCode(chart_code,#target_level,LEVEL) chart_code,
level,
SUM(debit) debit,
SUM(credit) credit
from acc_trial_balance_vw
where
convert(datetime,create_date,103) between convert(datetime, cast(#StartDate as datetime) , 103)
and convert(datetime, cast(#EndDate as datetime)+'23:59:59' , 103)
and company_code = #company_code
GROUP BY chart_code, LEVEL
Related
I have the following SProc, which works fine for me, but I am trying to create two parameters, to pass in two variables, and I actually have 0 parameters.
ALTER PROCEDURE [dbo].[TimeSeries]
AS
BEGIN
Drop Table UNION_SUMMARY
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
SELECT *
INTO UNION_SUMMARY
FROM
(
Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_TMP_MG_MORTGAGE_SCHED_HIST_SPLIT' AS TBL From TBL_TMP_MG_MORTGAGE_SCHED_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FMDDATA_HIST_SPLIT' AS TBL From TBL_FMDDATA_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_CDARS_HIST_SPLIT' AS TBL From TBL_FR2052A_CDARS_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_OperationalDepositTag_SPLIT' AS TBL From TBL_FR2052A_OperationalDepositTag_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_FXDH_REVAL_HIST_SPLIT' AS TBL From TBL_FR2052A_FXDH_REVAL_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_ACCOUNT_HIST_SPLIT' AS TBL From TBL_MULTI_ACCOUNT_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_LD_BALANCE_HIST_SPLIT' AS TBL From TBL_MULTI_LD_BALANCE_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_LD_HIST_SPLIT' AS TBL From TBL_MULTI_LD_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_SCHD_HIST_SPLIT' AS TBL From TBL_FR2052A_SCHD_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_MG_FUTURE_BALANCE_HIST_SPLIT' AS TBL From TBL_MULTI_MG_FUTURE_BALANCE_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_MM_HIST_SPLIT' AS TBL From TBL_MULTI_MM_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_TPOS_HIST_SPLIT' AS TBL From TBL_FR2052A_TPOS_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_AGG_BOC_HIST' AS TBL From TBL_FR2052A_AGG_BOC_HIST Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_NB_IU_HIST' AS TBL From TBL_FR2052A_NB_IU_HIST Where AsOfDate Between #StartDate AND #EndDate
) a
END
I would expect to see 2 parameters here, but I see 0.
You need it in the proc declaration...
ALTER PROCEDURE [dbo].[TimeSeries] (#StartDate DATETIME,#EndDate DATETIME)
as...
Because your SP has no parameters. In the context of your Procedure, #StartDate and #EndDate are variables.
To declare a parameter, you need to put them in your CREATE/ALTER clause. For example:
ALTER PROCEDURE [dbo].[TimeSeries] #StartDate datetime, #EndDate datetime AS
BEGIN
DROP TABLE dbo.UNION_SUMMARY;
SELECT *
INTO dbo.UNION_SUMMARY
...
END
The syntax is as follows:
ALTER PROCEDURE [dbo].[TimeSeries]
#StartDate DATETIME,
#EndDate DATETIME
AS
BEGIN
Drop Table UNION_SUMMARY
SELECT *
INTO UNION_SUMMARY
FROM
(
Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_TMP_MG_MORTGAGE_SCHED_HIST_SPLIT' AS TBL From TBL_TMP_MG_MORTGAGE_SCHED_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FMDDATA_HIST_SPLIT' AS TBL From TBL_FMDDATA_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_CDARS_HIST_SPLIT' AS TBL From TBL_FR2052A_CDARS_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_OperationalDepositTag_SPLIT' AS TBL From TBL_FR2052A_OperationalDepositTag_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_FXDH_REVAL_HIST_SPLIT' AS TBL From TBL_FR2052A_FXDH_REVAL_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_ACCOUNT_HIST_SPLIT' AS TBL From TBL_MULTI_ACCOUNT_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_LD_BALANCE_HIST_SPLIT' AS TBL From TBL_MULTI_LD_BALANCE_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_LD_HIST_SPLIT' AS TBL From TBL_MULTI_LD_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_SCHD_HIST_SPLIT' AS TBL From TBL_FR2052A_SCHD_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_MG_FUTURE_BALANCE_HIST_SPLIT' AS TBL From TBL_MULTI_MG_FUTURE_BALANCE_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_MULTI_MM_HIST_SPLIT' AS TBL From TBL_MULTI_MM_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_TPOS_HIST_SPLIT' AS TBL From TBL_FR2052A_TPOS_HIST_SPLIT Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_AGG_BOC_HIST' AS TBL From TBL_FR2052A_AGG_BOC_HIST Where AsOfDate Between #StartDate AND #EndDate
Union Select AsOfDate,Portfolio,PID,Reportable_Amount,'TBL_FR2052A_NB_IU_HIST' AS TBL From TBL_FR2052A_NB_IU_HIST Where AsOfDate Between #StartDate AND #EndDate
) a
END
Here i'm Trying to create stored procedure.. group by detepart..is it correct or wrong.??
CREATE PROCEDURE sp_NewvsOldOrders
(
#StartDate DATETIME,
#EndDate DATETIME
)
AS BEGIN
DECLARE #NewCount INT
, #NewRevenue INT
, #NewDate DATETIME
SELECT
#NewDate = DATEPART(DAY, od.OrderDate)
, #NewCount = COUNT(*)
, #NewRevenue = SUM((CONVERT(DECIMAL(18, 2), od.TotalAmount)))
FROM orderdetails od
INNER JOIN customer c
ON od.customerid = c.customerid
WHERE (CONVERT(DATETIME, (CONVERT(VARCHAR(50), od.orderdate, 101))) BETWEEN #StartDate AND #EndDate)
AND ((CONVERT(DATETIME, (CONVERT(VARCHAR(50), od.orderdate, 101)))) = (CONVERT(DATETIME, (CONVERT(VARCHAR(50), c.registereddate, 101)))))
AND (od.TransactionId IS NOT NULL)
AND (od.TransactionId <> '')
GROUP BY DATEPART(DAY, od.OrderDate)
, od.OrderDate
END
Perhaps this is how your stored procedures should be. As you didn't explain your requirement, i can really tell what you are trying to achieve
CREATE PROCEDURE sp_NewvsOldOrders
(
#StartDate DATETIME,
#EndDate DATETIME
)
AS BEGIN
-- not used
--DECLARE #NewCount INT
-- , #NewRevenue INT
-- , #NewDate DATETIME
SELECT
NewDate = DATEPART(DAY, od.OrderDate)
, NewCount = COUNT(*)
, NewRevenue = SUM((CONVERT(DECIMAL(18, 2), od.TotalAmount)))
FROM orderdetails od
INNER JOIN customer c
ON od.customerid = c.customerid
WHERE (od.orderdate >= StartDate)
AND (od.orderdate < DATEADD(DAY, 1, #EndDate))
AND (CONVERT(VARCHAR(50), od.orderdate, 101)
= CONVERT(DATETIME, c.registereddate, 101))
AND (od.TransactionId IS NOT NULL)
AND (od.TransactionId <> '')
GROUP BY DATEPART(DAY, od.OrderDate)
--, od.OrderDate
END
I have a sql table that has the following
ID StartDate EndDate
10 2015-12-01 2016-05-31
15 2016-01-05 2016-07-04
20 2016-02-10 2016-08-09
I need to break down the months like so...
ID StartDate EndDate
10 2015-12-01 2015-12-31
10 2016-01-01 2016-01-31
10 2016-02-01 2016-02-29
10 2016-03-01 2016-03-31
10 2016-04-01 2016-04-30
10 2016-05-01 2016-05-31
15 2016-01-05 2016-02-04
15 2016-02-05 2016-03-04
15 2016-03-05 2016-04-04
15 2016-04-05 2016-05-04
15 2016-05-05 2016-06-04
15 2016-06-05 2016-07-04
etc
I'm new to SQL so an example would be very helpful
Calendar
recommended if you have persistent Calendar/DateRanges table
declare #datebegin date = '20140101'
;with cteCalendar as
(
select
c.period_start,
dateadd(dd, -1, dateadd(mm, 1, c.period_start)) as period_end
from
(
select top 100
dateadd(mm, row_number() over(order by sc.object_id)-1, #datebegin) as period_start
from sys.columns sc
order by period_start
) c
),
cteData as
(
select cast(10 as int) as id, cast('20151201' as date) as StartDate, cast('20160531' as date) as EndDate
union all
select 15, '20160105', '20160704'
union all
select 25, '20160210', '20160809'
),
cteDataEx as
(
select d.id, d.StartDate, d.EndDate, datepart(dd, d.StartDate)-1 as DateOffset
from cteData d
)
select
d.id,
dateadd(dd, d.DateOffset, c.period_start) as StartDate,
dateadd(dd, d.DateOffset, c.period_end) as EndDate
from cteDataEx d
inner join cteCalendar c on c.period_start <= d.EndDate and c.period_end >= d.StartDate
where dateadd(dd, d.DateOffset, c.period_end) <= d.EndDate
order by id, StartDate
Actually I did not notice at the beginning that periods may start and end not at 1st day of month, so had to append some calculations after completion of the whole script. Later I realized that <= >= date filter produces unnecessary last row which overflows original date range high bound. So had to append final filter and after that modification don't like this approach totally )) May be some enhancements can be applied but I'm not interested in. Lots of ways to accomplish this task. Additional information about nature and purpose of periods given may alter relevance and applicability of different approaches
Recursion
no extra data required but recursion can be slow if date ranges can be wide enough.
;with cteData as
(
select cast(10 as int) as id, cast('20151201' as date) as StartDate, cast('20160531' as date) as EndDate
union all
select 15, '20160105', '20160704'
union all
select 25, '20160210', '20160809'
),
ctePeriods as
(
select
d.id,
d.StartDate,
dateadd(dd, -1, dateadd(mm, 1, d.StartDate)) as EndDate,
d.EndDate as _EndDate
from cteData d
union all
select
p.id,
dateadd(mm, 1, p.StartDate),
dateadd(dd, -1, dateadd(mm, 2, p.StartDate)),
p._EndDate
from ctePeriods p
where p.EndDate < p._EndDate
)
select p.id, p.StartDate, p.EndDate
from ctePeriods p
order by id, startdate
this code generate the rage of months, inclute leap year, but I don't undestand your need so explain better
create table #dia_meses
(mes int,
messtr varchar(2),
dia_final varchar(2))
insert into #dia_meses values(1,'01','31')
insert into #dia_meses values(2,'02','29')
insert into #dia_meses values(3,'03','31')
insert into #dia_meses values(4,'04','30')
insert into #dia_meses values(5,'05','31')
insert into #dia_meses values(6,'06','30')
insert into #dia_meses values(7,'07','31')
insert into #dia_meses values(8,'08','31')
insert into #dia_meses values(9,'09','30')
insert into #dia_meses values(10,'10','31')
insert into #dia_meses values(11,'11','30')
insert into #dia_meses values(12,'12','31')
declare #year varchar(4)
declare #contador int
set #year =convert(varchar,DATEPART(YEAR,GETDATE()))
set #contador =convert(varchar,DATEPART(month,GETDATE()))
declare #dataIni datetime
declare #datafim datetime
set #dataIni=(select #year+'-'+messtr+'-01' from #dia_meses where mes=#contador)
--pulo do gato ano bissexto
if(#contador=2)
begin
if(select ISDATE(#year+'-'+messtr+'-'+dia_final) from #dia_meses where mes=#contador)=0
begin
set #datafim=(select #year+'-'+messtr+'-28' from #dia_meses where mes=#contador)
end
else--ano bissexto
begin
set #datafim=(select #year+'-'+messtr+'-'+dia_final from #dia_meses where mes=#contador)
end
end
else
begin
set #datafim=(select #year+'-'+messtr+'-'+dia_final from #dia_meses where mes=#contador)
end
print #dataIni
print #dataFim
This will work on SQL Server 2012 and up; the EOMONTH function does not exist on earlier versions.
DECLARE #table TABLE (ID INT, StartDate DATE, EndDate DATE)
DECLARE #outtable TABLE (ID INT, StartDate DATE, EndDate DATE)
DECLARE #ID INT
DECLARE #StartDate DATE
DECLARE #Date1 DATE
DECLARE #Date2 DATE
DECLARE #EndDate DATE
INSERT INTO #table VALUES
(10,'2015-12-01','2016-05-31')
,(15,'2016-01-05','2016-07-04')
,(20,'2016-02-10','2016-08-09')
DECLARE tablecursor CURSOR FOR
SELECT * FROM #table
OPEN tablecursor
FETCH NEXT FROM tablecursor INTO #ID, #StartDate, #EndDate
WHILE ##FETCH_STATUS = 0
BEGIN
SET #Date1 = #StartDate
SET #Date2 = EOMONTH(#Date1)
WHILE #Date1 < #EndDate
BEGIN
PRINT CONVERT(VARCHAR,#ID) + ' ' + CONVERT(VARCHAR,#Date1) + ' ' + CONVERT(VARCHAR,#Date2)
INSERT INTO #outtable
SELECT #ID, #Date1, #Date2
SET #Date1 = DATEADD(DAY,1,#Date2)
SET #Date2 = EOMONTH(#Date1)
IF #Date2 > #EndDate
BEGIN
SET #Date2 = #EndDate
END
END
FETCH NEXT FROM tablecursor INTO #ID, #StartDate, #EndDate
END
SELECT * FROM #outtable
CLOSE tablecursor
DEALLOCATE tablecursor
I am trying to compare DateTime string to a DateTime Value Column in DB but its returning me 0 records Here is the query
DECLARE #p_date DATETIME
SET #p_date= CONVERT( DATETIME, '9/1/2015 10:06:22 PM', 131 )
SELECT UpdateUserId, UpdateTimeA
From SubmitSheets
WHERE CONVERT( DATETIME, UpdateTimeA, 131 ) = #p_date
the value in UpdateTimeA column is 2015-09-01 22:06:22.447
Like I said in my comment, I'm not sure 131 is the right style to convert to datetime (at least, I get a very different value).
If you want to compare dates without the second fraction, you'll have to compare as strings. Converting both dates to a varchar(19) will cut off the fractions.
Finally found a way
SELECT UpdateUserId,UpdateTimeA
From SubmitSheets
WHERE CONVERT(VARCHAR(16),UpdateTimeA,100) = CONVERT(VARCHAR(16),CONVERT( DATETIME, '9/1/2015 10:06:22 PM',101),100)
I think the #p_date parameter is not in same format. Try this:
DECLARE #p_date DATETIME
SET #p_date= CONVERT( DATETIME, '9/1/2015 10:06:22 PM')
SELECT UpdateUserId, UpdateTimeA
From SubmitSheets
WHERE CONVERT(DATETIME, (CONVERT(VARCHAR, UpdateTimeA, 101) + ' ' + CONVERT(VARCHAR, UpdateTimeA, 108)), 131) = CONVERT(DATETIME, #p_date, 131)
So another tryout may be
An example:
DECLARE #a TABLE
(
ID int,
datet datetime
)
INSERT INTO #a
(ID, datet)
VALUES (1 , CONVERT(DATETIME, GETDATE(), 131))
,(2 , CONVERT(DATETIME, GETDATE(), 131))
,(3 , CONVERT(DATETIME, GETDATE(), 131))
,(4 , CONVERT(DATETIME, GETDATE(), 131))
,(5 , CONVERT(DATETIME, GETDATE(), 131))
,(6 , CONVERT(DATETIME, GETDATE(), 131))
,(7 , CONVERT(DATETIME, GETDATE(), 131))
,(8 , CONVERT(DATETIME, GETDATE(), 131))
,(9 , CONVERT(DATETIME, GETDATE(), 131))
SELECT ID, datet, ConvDatetime
FROM
(
SELECT ID, datet
,CONVERT(DATETIME, (CONVERT(VARCHAR, datet, 101)
+ ' '
+ CONVERT(VARCHAR, datet, 108)), 131) AS ConvDatetime
FROM
#a
) AS dt
WHERE
dt.ConvDatetime= CONVERT(DATETIME,
(CONVERT(VARCHAR, GETDATE(), 101)
+ ' '
+ CONVERT(VARCHAR, GETDATE(), 108))
, 131) -- CONVERT( DATETIME, '9/1/2015 10:06:22 PM', 131 )
I'm trying to write a function to return the number of working days between 2 dates. I have a table with all the bank holidays in which has two fields: BHID and BHDate.
I've written the following SELECT query to test out my theory and it works nicely:
DECLARE #StartDate AS Date, #EndDate AS Date
SET #StartDate = '2015-01-01'
SET #EndDate = '2015-07-01'
;WITH CTE AS (
SELECT #StartDate AS StartDate, #EndDate AS EndDate, #StartDate AS DateCalc
UNION ALL
SELECT #StartDate AS StartDate, #EndDate AS EndDate, DATEADD(dd, 1, DateCalc) AS DateCalc FROM CTE
WHERE DATEADD(dd, 1, DateCalc) <= EndDate)
SELECT COUNT(*) AS Days
FROM CTE
LEFT JOIN psd.dbo.LUBankHolidays BH
ON CTE.DateCalc = BH.BHDate
WHERE BHID IS NULL
AND LEFT(DATENAME(dw, DateCalc) ,1) <> 'S'
option (Maxrecursion 0);
But when I try and put it in a function I get some errors around the SET line, it could be me just not being quite as good on functions as the rest of my knowledge or I was wondering whether it was to do with the CTE not having been used ahead of the SET line? Here's my attempt:
CREATE FUNCTION [dbo].[WorkingDays]
(#StartDate AS Date, #EndDate AS Date
)
RETURNS INT
AS
BEGIN
DECLARE #Days AS INT
;WITH CTE AS (
SELECT #StartDate AS StartDate, #EndDate AS EndDate, #StartDate AS DateCalc
UNION ALL
SELECT #StartDate AS StartDate, #EndDate AS EndDate, DATEADD(dd, 1, DateCalc) AS DateCalc FROM CTE
WHERE DATEADD(dd, 1, DateCalc) <= EndDate)
SET #Days =
(SELECT COUNT(*) AS Days
FROM CTE
LEFT JOIN psd.dbo.LUBankHolidays BH
ON CTE.DateCalc = BH.BHDate
WHERE BHID IS NULL
AND LEFT(DATENAME(dw, DateCalc) ,1) <> 'S'
option (Maxrecursion 0);)
RETURN #Days
END
I even tried inserting the result of the INT into a temporary table and then dropping this after setting #Days before then returning #Days but this then results in an error regarding not being allowed to produce temporary tables as part of a function.
Any help would be great, I'm sure it's a small thing but just escaping me currently.
Because a CTE can only be used in a query, rather than using SET to set the variable, use SELECT instead:
SELECT #Days =
(SELECT COUNT(*) AS Days
FROM CTE …
From MSDN:
A CTE must be followed by a single SELECT, INSERT, UPDATE, or DELETE
statement that references some or all the CTE columns.
Worked it out with stuartd's help:
CREATE FUNCTION [dbo].[WorkingDays]
(#StartDate AS Date, #EndDate AS Date
)
RETURNS INT
AS
BEGIN
DECLARE #Days AS INT
;WITH CTE AS (
SELECT #StartDate AS StartDate, #EndDate AS EndDate, #StartDate AS DateCalc
UNION ALL
SELECT #StartDate AS StartDate, #EndDate AS EndDate, DATEADD(dd, 1, DateCalc) AS DateCalc FROM CTE
WHERE DATEADD(dd, 1, DateCalc) <= EndDate)
SELECT #Days =
(SELECT COUNT(*) AS Days
FROM CTE
LEFT JOIN psd.dbo.LUBankHolidays BH
ON CTE.DateCalc = BH.BHDate
WHERE BHID IS NULL
AND LEFT(DATENAME(dw, DateCalc) ,1) <> 'S')
option (Maxrecursion 0);
RETURN #Days
END
Thanks All
Use this function
CREATE FUNCTION [dbo].[WorkingDays]
(#Start_Date AS Date, #end_Date AS Date
)
RETURNS INT
AS
BEGIN
DECLARE #Days AS INT
WITH AllDays
AS ( SELECT #start_date AS [Date], 1 AS [level]
UNION ALL
SELECT DATEADD(DAY, 1, [Date]), [level] + 1
FROM AllDays
WHERE [Date] < #end_date )
SELECT #Days =COUNT(*) AS Days
FROM AllDays
LEFT JOIN psd.dbo.LUBankHolidays BH
ON AllDays.Date= BH.BHDate
WHERE BHID IS NULL
AND LEFT(DATENAME(dw, AllDays.Date) ,1) <> 'S'
RETURN #Days
END