I'd like to have a data driven "schedule", meaning every report has it's unique time (stored in a table which is populated every minute) when it needs to go out.
For example: (not all fields included)
To Parameter Format NextRunDate ReportStatus
bob[at]email.com SalesRegion1 Email 1/1/2012 9:00:00 'Unprocessed'
joe[at]email.com SalesRegion2 Email 1/1/2012 9:05:00 'Unprocessed'
sara[at]email.com SalesRegion1 Email 1/1/2012 8:55:00 'Processed'
if the time is currently 1/1/2012 9:01:00 my Data Driven Subscription "where statement" would be something like...
where NextRunDate < GETDATE() -- in the past
and ReportStatus = 'Unprocessed' -- <--here is my problem
This query is run every minute. It should only pull the report for bob[at]email.com...
My problem is here:
I need to add logic that toggles the Report Status and 'Processed' once the report is sent... otherwise it runs every report every time...
Thoughts? Other ways to get this to work?
Running SQL Server 2k8 Enterprise
Thanks in advance!
If the reports are run on a similar cycle (every minute or every five minutes as in your code) you could use BETWEEN and DATEADD to subtract the number of minutes (whatever) to get to the last time you ran the report through to now.
{WHERE NextRunDate BETWEEN DATEADD(mi, -5, GETDATE()) AND GETDATE()}
I hope that helps.
Related
I have recently been putting together an SSRS report that will run every 15 minutes for the previous 15 minute 'chunk' of time. In essence a very straight forward and simple report that will run via an automated subscription.
I was using Microsoft SQL Server 12 Report Builder Version 3.
I was alerted to an issue with the output csv when my recipient reported being sent blank files, most odd considering the report generated as expected when run manually.
Long story short, it was the expressions I was using to generate the From and To dates. Manual runs produced data, subscription runs did not.
Original parameters
FromDate
dateadd(DateInterval.Second, (second(now()) + 900) * -1, dateadd(Dateinterval.Minute, (minute(now()) mod 15) * -1, now()))
ToDate
dateadd(DateInterval.Second, (second(now()) + 1) * -1, dateadd(Dateinterval.Minute, (minute(now()) mod 15) * -1, now()))
New Parameters
FromDate
dateadd(DateInterval.Minute, -15, dateadd(DateInterval.Minute, cint(datediff(DateInterval.Minute,today(),now()) / 15) * 15, today()))
ToDate
dateadd(DateInterval.Second, 899,Parameters!FromDate.Value)
Thought I would post this here for two reasons
Theories as to why
It might help someone in the future
Your original parameters take Now and subtract the minutes to arrive at a 15-minutes time, then they take the seconds of another Now (which is later and could be in the next second or even minute) and subtract that value to arrive at a 0-second time (or a 59-second time). This could already cause a problem when there is a change of seconds between the first and the second Now, which isn't very unikely, as on my test system there were 0.59 seconds between the two evaluations of Now in the FromDate parameter. Also, the Now value is more accurate than just a second, and your formula does not respect that. Therefore, if the records you are trying to process in your report happen to have a time of exactly a quarter of an hour, the first parameter is for sure greater (by maybe 0.01 second) and so the record is ignored.
Your formula for the "new parameters" does not depend on the seconds of Now() and will always return a time with no fraction of a second, so I guess that that's what makes the difference.
The expression for the FromDate could be simplified a little:
=Today.AddSeconds(900*(DateDiff(DateInterval.Minute, Today, Now)\15-1))
If you do not plan to run the report very short before midnight, there should not be a problem caused by a change of the day during the evaluation of Today and Now, and you could calculate the second parameter in a similar way, independently from the first one:
=Today.AddSeconds(900*(DateDiff(DateInterval.Minute, Today, Now)\15)-1)
The original parameter values were being calculated individually which means they would each have slightly different values for Now(). I know this is a long shot, but it's a theory. If the subscription job fired off a fraction of a second before a 15 minute interval, it's possible that the ToDate returned just before the FromDate. This would result in an invalid date range.
With the new expressions, the ToDate is referencing the FromDate which forces them to be calculated in sequence, not in parallel. Not to mention you're adding to the FromDate which also forces the date range to have a consistent length. However, you may still run into a case where you get the same report twice if the FromDate is calculated on the wrong side of a 15 minute cutoff.
One way to test/avoid this issue would be to offset the subscription time so that it doesn't actually try to fire at the exact 15 minute cutoffs. For example, you could have it scheduled to go off 1 minute afterwards.
I've got a client application that's going to update a database every five minutes with the current time, and then I want to output this time as a last active table in a seperate VB application.
I know about mysql time, but I don't quite understand how I can use it to display when a client was last active.
I've looked around and found some stuff about mysql times but I don't fully understand it.
Any help would be great, I'm going to place the results in a ListView with 'Client Name' and 'Last Active' if this helps, and I already know how to connect to my database and retrieve information.
Thank you.
I'd recommend using a DATETIME for storage. The TIME data type is limited to a single "time of day" or a timespan. True, you're looking for the time of day, but to calculate the "Last Active" time you need the date attached. Consider these "Last Active" values (using a 24-hour clock):
3/26/2013 at 17:00:00 <-- this has the maximum time (5PM), but...
3/27/2013 at 08:15:00 <-- ...this is the most recent time because it happens the following day
In other words, you need the date so you can sort the time.
The MySQL DATETIME data type should be supported by VB.NET, but I've never used the two together so I can't guarantee it. To query and report just the time component of the date you have a ton of options. Here are two:
Query the entire date/time from MySQL and return it as a System.DateTime value to VB.NET. In VB.NET you can format it using DateTime.ToString to show only the time components. The MySQL query would go something like this:
SELECT ClientName, MAX(LastActive) AS LastActiveDateTime
FROM your_table
GROUP BY ClientName
Format the time in MySQL and return it as a String to VB.NET. In VB.NET you'll just need to display the string as is. The MySQL query would go something like this:
SELECT ClientName, DATE_FORMAT(MAX(LastActive), '%r') AS LastActiveTime
FROM your_table
GROUP BY ClientName
The format code %r in the above query will return the time in a 12-hour format with AM/PM, for example 07:55:29 PM. To return a 24-hour format (19:55:29), use %T instead.
I have an SSRS 2005 report that has a dataset for to an Oracle database. The report that i have essentially just pulls all data back from an audit log. This report works perfectly fine and i have scheduled thi to run and send an email using the new subscription method within SSRS.
The only issue i have is i want the report to run on the last day of the month (its set up to do this alreday) and run the report based on that month only. Getting the report to run specifically for a month is what im unsure on? I though i would be able to set parameters within the report but these only enable my user to select a calendar date?
Is there a DATEADD or DATEPART type of function i can use to complete this task?
Regards
B
Best bet would be to set up a dynamic date default for the date patameter at the report level, and set up the subscription to use this default value, so whenever the subscription runs it would automatically have the appropriate date.
Probably the easiest thing to do is set the parameter as the current date, if that would work, e.g. something like =Today(). So that will be calculated whenever the subscription runs.
You can set the default value for whatever you need; first day of the current month, etc. You should able to set whatever value you need without too much trouble.
So for the first day of the month something like:
=DateSerial(Year(Today()), Month(Today()), 1).
Users running the report ad-hoc could just reset the parameter as required.
I'm assuming the report handles the amount of data to return correctly assuming the right data parameter is sent.
2 Parameters #DateFrom and #DateTo
Default Value for #DateFrom that outputs the first day of the current month:
=DateAdd("d",-Day(Today())+1,Today())
Default Value for #DateTo that outputs the last day of the current month:
=DateAdd("d",-Day(Today())+1,DateAdd("m",1,Today()))
Scenario:
I have a lookup table which has a date column, I need to look at this date column and check if its today's date, if not then wait for 5 mins and check the same thing again, and if the date is current send an email and exit the loop, and if after 6 retries if the date is not current execute a SQL task.
I have a ForLoop Container with the following settings:
InitExpression : #[User::Counter] = 0
EvalExpression : #[User::Counter] < 6
AssignExpression : #[User::Counter] = #[User::Counter] + 1
How / Where do I check the date :
SELECT ControlTimeStamp from LOOKUPTABLE
WHERE ControlTimeStamp = DATEADD(dd, 0, DATEDIFF(dd, 0, GETDATE()))
Note:
I'm using Business Intelligence Development Studio (BIDS) 2008 for SSIS package development.
I think you'll want an approach like this. Execute your SQL Task to determine whether today is your date. From there you'll need to either sleep for N minutes or you'll want to send an email. The trick is to use an Expression on the Precedence Constraint between the Execute SQL Task the children.
My implementation differs slightly from what yours but the concept remains the same. I created two variables, #ActualDate and #ReferenceDate. #ActualDate is today and #ReferenceDate gets set from the Execute SQL Task. I then see whether they are equivalent. For what you have, if you get a result, then you know the send mail condition has been met so change your Expressions to meet that.
What isn't shown is how to terminate the loop early as I'm not quite certain how to do that.
System - SSRS 2008R2 using report builder 3.0 (or BIDS if you think the answer lies there)
Objective - Create a report that displays sales data from the past 24 hours for each sales region. The report needs to refresh every 10 minutes, and always show the last 24 hours from the last refresh. However - the users still need to have the ability to change the time frame.
What did I do?
Built a report that shows sales data for a single region depending on 3 parameters: StartTime, EndTime, RegionCode. Lets call it RegionalSales
Built a master report that includes multiple subreports of RegionalSales. the master report has 2 parameters - StartTime (with a default value dateadd("h",-24,Now())) and EndTime (with a default value Now()). I am sending StartTime and EndTime to the subreports, and every subreport is assigned it's own region.
I've set the Auto-Refresh property of the master report to 600.
Results -
At first everything seems perfect - the master report loads, and the data shown is correct for the loading time (let's say 22:08). However, after the auto-refresh (that occures at 22:18) the data is still correct as to 22:08.
The problem is that on the first load of the report the parameters get their default values as I stated (StartTime = 10/12/2011 22:08 & EndTime = 11/12/2011 22:08).
However, on the auto-refresh instead of the paramters updating (So I'll get StartTime = 10/12/2011 22:18 & EndTime = 11/12/2011 22:18) I still get the old values (StartTime = 10/12/2011 22:08 & EndTime = 11/12/2011 22:08)
Any thought on why, and how can I change this?
Thanks!
If I understand correctly...
Unfortunately, report parameters get their values only at the first load unless the user manually clicks the View Report button.
To get around this, I'd try converting the date parameters to not use default values, but rather get their values from a query and use the equivalent of GETDATE() for your RDBMS. If I'm not mistaken this will require you to add another DataSet to your report... but it won't really be a dataset since the query for it will simply be SELECT GETDATE() [or the equivalent for your RDBMS] and whatever transformations you need to do for that.