SSRS default parameter values in subscription - reporting-services

I have a report that has two required date parameters which the user enters. I want to create a subscription that runs on Friday that pulls for the previous week's Sunday through Saturday period. So for example, for this coming Friday, the subscription would pull for Jan 29 - Feb 4. I've tried =Now(), =Today(), #ExecutionTime and then subtracting the number of days but all I get is errors. Is this possible to do?
I did see this link but I wonder if there's a better way.
http://www.sqlservercentral.com/articles/Development/datadrivensubscriptions/2432/
SSRS 2008

Yes I have done this, see this post https://stackoverflow.com/a/5539615/168703
You can create a dataset that gets date ranges and use it in your report. Then your subscription can use this date range and change on its own dynamically without manual changes every day/week/month/year/etc.
Reposted here as well, this is your most flexible solution:
I'll also share a set of common date functions I use. Just create this as a table valued function:
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
CREATE FUNCTION [dbo].[udfCommonDates] (#date datetime)
RETURNS #t table (week_start datetime,
week_end datetime,
lastweek_start datetime,
lastweek_end datetime,
month_start datetime,
month_end datetime,
lastmonth_start datetime,
lastmonth_end datetime,
yesterday_start datetime,
yesterday_end datetime,
today_start datetime,
today_end datetime,
thisweek_monday_start datetime,
thisweek_monday_end datetime,
year_start datetime,
year_end datetime,
tomorrow_noon datetime,
today_noon datetime,
date_only datetime)
BEGIN
INSERT #t
SELECT
dbo.get_week_start ( #date ) AS week_start,
dbo.get_week_end ( #date ) AS week_end,
dbo.get_week_start ( DATEADD(d, -7, #date ) ) AS lastweek_start,
dbo.get_week_end ( DATEADD(d, -7, #date ) ) AS lastweek_end,
dbo.get_month_start( #date ) AS month_start,
dbo.get_month_end ( #date ) AS month_end,
dbo.get_month_start ( DATEADD(m,-1, #date) ) AS lastmonth_start,
dbo.get_month_end ( DATEADD(m,-1,#date) ) AS lastmonth_end,
dbo.get_yesterday_start ( #date ) AS yesterday_start,
dbo.get_yesterday_end ( #date ) AS yesterday_end,
dbo.get_today_start (#date) AS today_start,
dbo.get_today_end ( #date ) AS today_end,
dbo.get_weekday_start(1,#date) AS thisweek_monday_start,
dbo.get_weekday_end(1,#date) AS thisweek_monday_end,
dbo.get_year_start(#date) AS year_start,
dbo.get_year_end(#date) AS year_end,
dbo.get_tomorrow_noon(#date) AS TomorrowNoon,
dbo.get_today_noon(#date) AS TodayNoon,
dbo.get_date_only(#date) AS DateOnly
RETURN
END
Here are the scalar valued functions for these:
CREATE FUNCTION [dbo].[get_date_only] (#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN dateadd(day, DateDiff(day, 0, GetDate()), 0)
END
GO
CREATE FUNCTION [dbo].[get_month_end] (#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN dateadd(ms, -3, dateadd (m,datediff(m,0,
dateadd(m,1,#date)),0))
END
GO
CREATE FUNCTION [dbo].[get_month_start] (#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS
BEGIN
RETURN dateadd(m,datediff(m,0, #date),0)
END
GO
CREATE FUNCTION [dbo].[get_today_end] (#today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS
BEGIN
return dateadd(ms, -3, datediff(d,0,dateadd(d,1,#today)))
END
GO
CREATE FUNCTION [dbo].[get_today_noon](#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN DATEADD(hh, 12, DATEADD(d,DATEDIFF(d,0, #date),0))
END
GO
CREATE FUNCTION [dbo].[get_today_start] (#today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(day, 0, datediff(d,0,#today))
END
GO
CREATE FUNCTION [dbo].[get_tomorrow_noon](#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN DATEADD(hh, 12, DATEADD(d,DATEDIFF(d,-1, #date),0))
END
GO
CREATE FUNCTION [dbo].[get_week_end] (#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(yyyy, datepart(yyyy,
dateadd(weekday,7-datepart(weekday, #date),#date))-1900, 0)
+ dateadd(ms, -3,
dateadd(dy, datepart(dy,
dateadd(weekday,7-datepart(weekday, #date),#date)),0) )
END
GO
CREATE FUNCTION [dbo].[get_week_start] (#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(yyyy, datepart(yyyy,
dateadd(weekday,1-datepart(weekday, #date),#date))-1900, 0)
+ dateadd(dy, datepart(dy,
dateadd(weekday,1-datepart(weekday, #date),#date))-1,0)
END
GO
CREATE FUNCTION [dbo].[get_weekday_end] (#weekday tinyint,
#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(yyyy, datepart(yyyy,
dateadd(weekday,#weekday-
datepart(weekday, #date),#date))-1900, 0)
+ dateadd(ms, -3,
dateadd(dy, datepart(dy,
dateadd(weekday,#weekday-datepart(weekday, #date),
#date)),0) )
END
GO
CREATE FUNCTION [dbo].[get_weekday_start] (#weekday tinyint,
#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(yyyy, datepart(yyyy,
dateadd(weekday,#weekday-
datepart(weekday, #date),#date))-1900, 0)
+ dateadd(dy, datepart(dy,
dateadd(weekday,#weekday-datepart(weekday, #date),
#date))-1,0)
END
GO
CREATE FUNCTION [dbo].[get_year_end] (#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN DATEADD(year, DATEDIFF(year, 0, GetDate())+1, 0)-1
END
GO
CREATE FUNCTION [dbo].[get_year_start] (#date datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN DATEADD(year,DATEDIFF(year,0, #date),0)
END
GO
CREATE FUNCTION [dbo].[get_yesterday_end] (#today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
return dateadd(ms, -3, datediff(d,0,#today))
END
GO
CREATE FUNCTION [dbo].[get_yesterday_start] (#today datetime)
RETURNS datetime
WITH SCHEMABINDING, RETURNS NULL ON NULL INPUT
AS BEGIN
RETURN dateadd(day, -1, datediff(d,0,#today))
END
GO
These were really helpful for me because I used this in reporting services for date parameters. You could simply create a dataset referencing this table function and then use these in the parameters for any datetime within RS.
You could execute this entire table-valued function like so:
SELECT * FROM [MyDB].[dbo].[udfCommonDates] (GetDate())
The result is like so
For Reporting Services Folks
Now I mentioned earlier that I use these for reporting services.
Now the RS folks might be thinking but how does this help me as I need a dataset and a dataset can only be based on a Stored Procedure or a direct table. No problem create the following stored procedure:
CREATE PROCEDURE [dbo].[uspCommonDates] AS
begin
set datefirst 1
declare #date datetime
set #date = getdate()
select * from dbo.udfCommonDates(#date)
end
Now you've got a stored procedure to use as a dataset...Now in reporting services add a new dataset:
Now go to the report parameters section of the report:
Now pick that dataset dsFunctions (or whatever you called it) and then pick any of the value fields from the scalar functions such as:
Now when you run the report it uses the scalars:
Also now in your "Subscription" you will see a "Use Default" checkbox next to the
parameter for the date. If you check this checkbox it will automatically use the default
value provided by this custom function. It is very very flexible and a very nice solution in reporting services. Here is a screen print of that:

On the report parameter configuration (on development time, not on the subscription creation), add a default value for the parameter. If you do, you will have a check box called "use default value" when creating the subscription

My favorite trick to handle this situation is to create an Integer parameter called StartWeek. Prompt of "The week starting:" Available values like:
Value Label
-4 =dateadd("d",0-weekday(today)+2+(-4*7),today).ToString("m")
-3 =dateadd("d",0-weekday(today)+2+(-3*7),today).ToString("m")
-2 =dateadd("d",0-weekday(today)+2+(-2*7),today).ToString("m")
-1 Previous Week
0 Current Week
1 Last Month
2 This Month
Default value of -1.
Then in your query:
DECLARE #StartDate DATETIME
DECLARE #EndDate DATETIME
DECLARE #CurrentDate DATETIME
SET #CurrentDate = GETDATE()
--SET #CurrentDate = 'October 31, 2011' -- for debugging
IF ( #StartWeek > 0 )
BEGIN
SET #StartDate = DATEADD(mm, DATEDIFF(mm, 0, #CurrentDate), 0)
SET #StartDate = DATEADD(mm, 2 - #StartWeek, #StartDate)
SET #EndDate = DATEADD(s, -1, DATEADD(mm, 1, #StartDate))
END
ELSE
BEGIN
SET #StartDate = DATEADD(wk,
DATEDIFF(wk, 0, DATEADD(d, -1, #CurrentDate))
+ #StartWeek, 0)
SET #EndDate = DATEADD(s, -1, DATEADD(day, 7, #StartDate))
END
Select
*
FROM
MyTable
WHERE
BeginDate <= #EndDate
AND FinishDate >= #StartDate

BeginDate
=DateAdd("d", -12, Today())
EndDate
=DateAdd("d", -6, Today())
So for the upcoming Friday 2/10. This would give you a date range of 1/29 - 2/4.

Related

Check Each Date In Date Range

In SQL Server 2008 I have a startdate and an enddate being passed to my procedure. I need to check each date in the range to see if it exists in my validworkday table. I have no clue where to begin on this, but this is how start/end day are set-up
Declare #startdate date, #enddate date
Set #startdate = '01/01/2015'
Set #enddate = '04/16/2015'
Now how can I iterate each date in this span to see if validworkday = true for it? The check I would need to run is like so (checking each date)
Select isvalidworkday
from validworkdays
where date = '01/01/2015'
Select isvalidworkday
from validworkdays
where date = '01/02/2015'
This is syntax that I found from #Incidently years ago (I don't remember where that original post is, but hopefully this will be enough to give the credit), that I still use today. All I did was slightly tweak his syntax to insert the data into a temp table and add a cursor to iterate each individual date.
DECLARE #DateFrom smalldatetime, #DateTo smalldatetime, #firstdate date;
SET #DateFrom='20000101';
SET #DateTo='20081231';
-------------------------------
WITH T(date)
AS
(
SELECT #DateFrom
UNION ALL
SELECT DateAdd(day,1,T.date)
FROM T
WHERE T.date < #DateTo
)
SELECT date
INTO #AllDates
FROM T OPTION (MAXRECURSION 32767);
Declare c1 Cursor For
Select date
FROM #AllDates
Open c1
Fetch Next From c1 Into #firstdate
While ##FETCH_STATUS = 0
Begin
--Do whatever processing you need here
Fetch Next From c1 Into #firstdate
End
Close c1
Deallocate c1
Code should only live in one place and not be rewritten. Create functions (once) like GetAllIntsBetween(), GetAllMonths(), GetAllDates(), etc. Then used them like:
DECLARE #startdate date = '01/01/2015', #enddate date = '04/16/2015'
SELECT allDates.TheDate,
isnull(v.isvalidworkday, false) AS isvalidworkday
FROM dbo.GetAllDates(#startdate, #enddate) AS allDates
LEFT JOIN validworkdays AS v
ON allDates.TheDate = v.MyDate
The GetAllDates() would be:
CREATE FUNCTION dbo.GetAllDates(#Start DATETIME, #End DATETIME)
RETURNS
#AllDates TABLE
(
TheDate DATETIME
)
AS
BEGIN
IF #Start > #End
BEGIN
DECLARE #Temp DATETIME
SET #Temp = #Start
SET #Start = #End
SET #End = #Temp
END
WHILE #Start <= #End
BEGIN
INSERT INTO #AllDates
VALUES(#Start)
SET #Start = DATEADD(DAY, 1, #Start)
END
RETURN
END
(note: can change DATETIME to DATE)

How many equal days are between two date ranges, SQL

I have table with date ranges, like this:
DATE DATE2
14.03.2013 17.03.2013
13.04.2013 02.05.2013
I have to create a procedure, that returns day count that is equal to two date ranges, one which is in the table and another one.
Forexample, I have date range in the table like this 14.03.2013 - 17.03.2013 and another one, which is declared in procedure like this 02.03.2013 - 16.03.2013, so in this case day count would be 3, because, both date ranges have dates between 14.03.2013 and 16.03.2013.
suppose your table is called daterange and you have parameters defined #param1 and param2 in your procedure then something on these lines should work:
set #param1 := cast('2013-03-14' as date);
set #param2 := cast('2013-03-16' as date);
select
datediff(least(date2,#param2),#param1)+1
from daterange where #param1 between date1 and date2
See example in sqlfiddle
You should be able to adapt this T-SQL function to MySQL
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[fu_RPT_OverlappingDateRangesDays]') AND type in (N'FN', N'IF', N'TF', N'FS', N'FT'))
DROP FUNCTION [dbo].[fu_RPT_OverlappingDateRangesDays]
GO
-- ======================================================================================================================
-- Author: Stefan Steiger
-- ALTER date: 11.06.2015
-- Alter date: 11.06.2015
-- Description: Calculate the number of overlapping days in two date-ranges
-- http://stackoverflow.com/questions/20836429/how-to-gets-the-number-of-overlapping-days-between-2-ranges
-- ======================================================================================================================
-- DECLARE #firstStart datetime
-- DECLARE #firstEnd datetime
-- DECLARE #secondStart datetime
-- DECLARE #secondEnd datetime
-- SET #firstStart = '01.01.2015'
-- SET #firstEnd = '31.01.2015'
-- SET #secondStart = '15.01.2014'
-- SET #secondEnd = '15.02.2015'
-- SELECT dbo.fu_RPT_OverlappingDateRangesDays( #firstStart, #firstEnd, #secondStart, #secondEnd )
CREATE FUNCTION [dbo].[fu_RPT_OverlappingDateRangesDays]
(
#firstStart datetime
,#firstEnd datetime
,#secondStart datetime
,#secondEnd datetime
)
RETURNS integer
AS
BEGIN
DECLARE #maxStart datetime
DECLARE #minEnd datetime
DECLARE #interval int
IF #firstStart IS NULL OR #firstEnd IS NULL OR #secondStart IS NULL OR #secondEnd IS NULL
-- RETURN 0
RETURN NULL
IF #firstEnd < #firstStart
RETURN 0
IF #secondEnd < #secondStart
RETURN 0
SET #maxStart = #secondStart
SET #minEnd = #secondEnd
IF #firstStart > #secondStart
SET #maxStart = #firstStart
IF #firstEnd < #secondEnd
SET #minEnd = #firstEnd
-- PRINT #maxStart
-- PRINT #minEnd
--SET #interval = DATEDIFF(DAY, #maxStart, #minEnd) + 1
SET #interval = {fn timestampdiff(SQL_TSI_DAY, #maxStart, #minEnd)} + 1
IF #interval < 0
SET #interval = 0
-- PRINT #interval
RETURN #interval
END
GO

Is it possible to set current date in stored procedure parameter?

I want to set GetDate() as default parameter value. But it shows error. Below is my block of code:
Create Proc XYS
(
#myDate datetime = GetDate() //error
)
AS
SET #myDate = GetDate() // i can do this but neither i want this nor I want to
pass current date from front end or upper layer
....
....
As far as i know functions/dynamic values are not supported as this level, instead we are allowed hardcoded values. Any workaround?
Would suggest using a value (e.g. 0 = minimum datetime) and then checking for it in your stored proc:
Create Proc XYS
(
#myDate datetime = 0)
AS
BEGIN
IF #myDate = 0
SET #myDate = GetDate()
// ...
END
I'm not saying it's the best idea in the world but it works for me:
CREATE VIEW dbo.V_GetDate
AS
SELECT GETDATE() AS TheDate
then
Create Proc XYS
AS
declare #myDate datetime
Select #myDate = TheDate from dbo.V_GetDate

Stripping the time out of datetime SQL Server 2005

I think I'm going crazy here.
I am trying to do a SP on SQL Server 2005 which takes a date, looks it up in another table and assigns a period number and week number (for financial calendar purposes).
The output needs to hold the date as a string, rather than datetime.
I simply CANNOT get the date to show without the time behind it.
I have tried a couple of methods:
select cast(floor(cast(#CalcDate as float)) as datetime)
I have made a function which converts it into a string and puts it back out again:
CREATE FUNCTION dbo.DateToVarchar (#DateIn datetime)
RETURNS varchar(10)
AS
BEGIN
declare #DD [varchar] (2)
declare #MM [varchar] (2)
declare #YYYY [varchar] (4)
declare #DateOut [varchar] (10)
declare #DDLen [int]
declare #MMLen [int]
set #DD = datepart(dd,#DateIn)
set #DDLen = len(#DD)
set #DD = (case when #DDLen < 2 then '0' + #DD else #DD end)
set #MM = datepart(mm,#DateIn)
set #MMLen = len(#MM)
set #MM = (case when #MMLen < 2 then '0' + #MM else #MM end)
set #YYYY = datepart(yyyy,#DateIn)
set #DateOut = #YYYY + '-' + #MM + '-' + #DD
return #DateOut
END
When I run the above function outside of the SP I get the date back just fine. When I run it through the SP it comes back as 2012-12-30 00:00:00.000
The variable #CalcDate is declared as a varchar(10)
Any ideas?
Thanks in advance
EDIT
Here is the body of the SP so far:
declare #StartDate [datetime]
, #EndDate [Datetime]
, #CalcDate [datetime] --This number will change in the WHILE loop to reflect the increment of days
, #Week [varchar]
, #Period [varchar]
, #i [int]
, #Year [int]
, #CalcDay [int]
, #CalcMonth [int]
, #CalcYear [int]
, #ConcatDate [char] (10)
set #StartDate = '2012-12-30'
set #EndDate = '2013-01-28'
set #Year = 2013
set #i = -1
-- Going to do a while loop here and instead of Week number and Period Number I'm going to do some calculations
set #Week = (Select WeekNum from aaGreensPeriodListTest Where PeriodNum = 1 and WeekNum = 1)
set #Period = (Select PeriodNum from aaGreensPeriodListTest Where PeriodNum = 1 and WeekNum = 1)
set #CalcDate = #StartDate + #i
set #CalcMonth = datepart(mm,#calcdate)
insert into aaGreensPeriodTest(RealDate,GreensYear,GreensPeriod,GreensWeek)
values (#CalcDate,#Year,#Period,#Week)
select #CalcDate as CalcDate, #CalcMonth as CalcMonth
SQL Server 2005 does not support date type without time part.
If your need to get date as a string you can use convert function. For example:
declare #date datetime;
set #date = getdate();
select convert(varchar, #date, 101) -- that will return date in ‘mm/dd/yyyy’ format
If you need a datetime variable without time part for some calculations, you can use an expression below:
declare #date datetime;
set #date = getdate();
select dateadd(dd, datediff(dd, 0, #date), 0)
As per http://msdn.microsoft.com/en-ca/library/ms187928.aspx, you cannot cast float->date directly. It's simply not supporte. But you can cast a datetime->date, so you'll have to double-cast. Or given your example, triple-cast:
CAST(CAST(CAST(#CalcDate AS float) AS datetime) AS date)

How to find the 1st date of previous month in mysql?

I am not able to run this function, is there any changes in this:
CREATE FUNCTION [GetFirstDateofMonth]
(#Date as DateTime)
RETURNS DateTime AS
BEGIN
Declare #FirstDate DateTime
Set #FirstDate = DateAdd(Day, 1, #Date - Day(#Date) + 1) -1
RETURN #FirstDate
END
CREATE FUNCTION [GetLastDateofMonth]
(#Date as DateTime)
RETURNS DateTime AS
BEGIN
Declare #LastDate DateTime
Set #LastDate = DateAdd(Month, 1, #Date - Day(#Date) + 1) -1
RETURN #LastDate
END
Assuming you want it relative to "now":
select subdate(adddate(last_day(now()), 1), interval 2 month)
replace now() with whatever you want if it's relative to some date other than "now"