How to set SSRS subscription time as an expression - sql-server

I have a report and the report StartDate and EndDate parameters are using the expression as a default value below.
=DateAdd(DateInterval.Minute,0,DateAdd("h",7,DateAdd("h",-24,Today())))
=DateAdd(DateInterval.Minute,0,DateAdd("h",7,Today()))
When I execute the report, the report is starting from the day before at 7 AM to today 7 AM.
I would like to keep the report Start time and End time like this(07:00).
I also want to send the report to customer every day 7:30 AM but the report needs to be executed according to start date and end date paramaters.
Example: today 12.12.2019
Subscription time will be 07:30 AM
report needs to be running this time:
StartDate : 11/12/2019 07:00:00
EndDate : 12/12/2019 07:00:00
But when I schedule subscription every day and 7:30 AM, I received report from one day before 7:30 AM and today 7:30 AM.
I just want to see report from 7:00am to 7 am. Even if I change schedule time.
Could you please help me about this problem. How can I edit my subscription?
Is it possible to write an expression in "date/time from - date/time to" fields in subscription?

Btw, When I unclick “use Default” part, it always takes 11-12-2019 even 2 days after ☹
Time from needs to be one day before at 07:00 AM
Time to should be on that day at 07:00 AM
Do you have any suggestion for it?
Thanks

I resolved my issue. There are 2 solutions for it.
Option 1 :
In the report design If it is must to have those date parameters must be DATTEIME and to allow TIME factor as well then and if you want to run the report which is subscribed always for Yesterday 7:00 to today 7:00 am then I would not rely on sending any parameter values based on expressions …I would set up Date/Time Parameter in report design to allow null values and send null values as default from the subscription settings.
Then In report SP you can always add a clause at the TOP like
if #startDateTime is null AND #endDateTime is null
begin
set #startDateTime =CONVERT(VARCHAR(10), getdate(), 111);
set #startDateTime =dateadd(hh,7,( dateadd(d,-1,#startDateTime)))
set #endDateTime =dateadd(d,1,#startDateTime)
end
and let the rest SP be same
Option 2 :
If you can change the report parameters to be a type only DATE then its easy always send =Today() in your subscription parameter for both Start & End
Then In report SP you can always add a clause at the TOP like
if #startDateTime = #endDateTime
begin
set #endDateTime =CONVERT(VARCHAR(10), #endDateTime, 111);
set #endDateTime =dateadd(hh,7,#endDateTime)
set #startDateTime =dateadd(d,-1,#startDateTime)
end
and let the rest SP be same
Option 2 is better if they are ok to have Start & End date parameter as just DATE instead of DATETIME.
Any way Using any of these options do handle this in SP… you can always have control in future if they want to change time form 7:00 am to any other time …no need to change report design just update SP…2 minutes
You can schedule this report for any time of the day and it will always send them a report for Yesterday 7:00 to Today 7:00

Related

Changing Date Parameter to Day Before

In short I have a stored procedure which accept a date parameter. This stored procedure is being called using Linq-to-SQL.
Procedure Code:
ALTER PROCEDURE [dbo].[usp_Artemis_Tracking_SalesData]
#ShopID int,
#StartDate Date,
#EndDate Date,
#Daily bit
AS
BEGIN
SET NOCOUNT ON;
SELECT #EndDate;
....
END
If I call the procedure using the following
Dim Var = MyProc(#3/1/2021#, Today)
It passes the two dates seen as 3/1/2021 00:00:00 and 3/11/2021 00:00:00 (today is the 11th) but the parameters in SQL are getting the second variable as 3/10/2021 (the day BEFORE)
BUT
If I change the call to
Dim Var = MyProc(#3/1/2021#, Today.ToShortDateString)
then SQL Server sees the second variable as 3/11/2021...
This is also true if I pass it as #3/11/2021# but if I use the Today function or actually any variable typed as Date it gets pushed back to the day before.
Side note: If I add an hour to the date, so that I pass Today.AddHour(1) then I get the 11th again in SQL
Help!
To get rid of the confusion about midnight, let's pretend we added one minute to 3/11/2021 00:00:00. Now it is one minute after midnight on 3/11 or 3/11/2021 12:01:00 AM. As you can see you are sending 3/11/2021 12:00:00 AM. Nothing that happened on 3/11 will be included unless it happened on the stroke of midnight.
Simply add a day to the second parameter. That will take you to midnight on 3/11 or 12AM on 3/12
Dim Var = MyProc(#3/1/2021#, Today.AddDays(1))

SSIS Package, execute every 13 hours for previous 12 hours of data

I have a SSIS Package and I need to schedule it to run at 1:00 AM and 1:00 PM every day.
At 1:00 AM it should pass parameters of the previous day for e.g.
15 Nov 2018 12:00 PM as #StartDate & 15 Nov 2018 11:59 PM as #EndDate
At 1:00 PM it should pass parameters of the current day for e.g.
15 Nov 12:00 AM as #StartDate & 15 Nov 11:59 AM as #EndDate
A stored procedure is called through an OLE DB Source Editor task in Data Flow.
Does anyone have any suggestions that How I could achieve this noting the fact that if the job fails at 1:00 PM & it should re-run at 2:00 PM, it should still pass the same parameters.
Here are the steps to pass the date parameters to OLEDB task.
Have start date & end date parameters in (I suppose you must be having).
Assign the dates values to both parameters using SQL task.
Pass these parameters to OLDEB stored procedure to data flow task.
For scheduling:
Create two different jobs for each run, one for 1 AM & another for 2 AM of the job.
For second job run, implement the following steps.
Create a table which log the job execution status with date and time. That table has insertion after each run of the job.
When second job schedule execute first check log table in first step and check the last run status of the job.
If it was successful exit else go to next step.
Hope this will help.

SQL Server - notify 30,15, 7 days from time

I'm trying to right an SQL Query that will do the following task:
Example:
ExpirationDate = '2018-04-30 00:00:00.000'
when the property is set to expire in 30 days ... 1 month before, I want SQL Server to email me informing that the item is about to expire based upon (Expirationdate)
could someone please give me some pointers as to where I go next... this is what I have tried so far..
the query below will find the item however I now want SQL Server Agent to send me an email for each row that is returned, not when nothing is returned
SELECT *
FROM [dbo].[Property]
WHERE expirationdate <= DateAdd(day ,30 , GetDate())
Here is an excellent link on how to email results from a sql server job agent:
https://www.brentozar.com/archive/2014/10/send-query-results-sql-server-agent-job/
As for your query: I wouldn't SELECT *. Explicitly select the columns you want returned in your email response.
Next I would define a variable to hold the value of your cutoff, this will prevent you doing a calculation for each row within the query. Example:
DECLARE #day30UpperBound DATETIME = DATEADD(Day, 31, cast(getdate() as date));
DECLARE #day30LowerBound DATETIME = DATEADD(Day, 30, cast(getdate() as date));
Then you can query results with:
SELECT explicitColumnList FROM [dbo].[Property]
WHERE expirationdate BETWEEN #day30LowerBound AND #day30UpperBound
This specific example should give you those Properties with an expiration date that fall in the window of 30 days from current at midnight, to 31 days from current at midnight - so a full 24 hour window 30 days from current day.
You can easily reproduce this for your 15 day, and 7 day reports. You could put all 3 reports into one job agent. Or you could make a different job for each of the 3.
You'll have to research a little on how to do only business days if that's what you want.

SQL Server Assign Conditional Variable in Select Statement

I am not an SQL expert and need some help in figuring this out. I am writing a payroll application with SQL Server 2012 database that need to keep track of time user punched in , punched out and then calculate work time and other calculations based on work time. Work time is computed as time between 9:30 a.m. and 5:30 p.m. Here is the logic:
if the user punches in earlier than 9:30 a.m., work start time is set
to 9:30 a.m.
If the user punches in later than 9:30 a.m. work start time would be
actual time punched in.
if the user punches out after 5:30 p.m. work end time would be set at
5:30 p.m.
if the user punches out before 5:30 p.m. work end time would be set
to actual punch out time
Here the partial SQL I tried but not getting anywhere. Any help would be appreciated:
declare #start time;
declare #end time;
select #start=cast('09:30:00.0000000' as time)
select #end=cast('17:30:00.0000000' as time)
SELECT Datename(dw,LastUpdate) as WeekDay
,FORMAT(PunchIn,'MM/dd/yyyy hh:mm tt') as PunchIn
,FORMAT(PunchOut,'MM/dd/yyyy hh:mm tt') as PunchOut
,case
--employee punched in before 9:30 so take 9:30 as start time
when datediff(mi,#start,cast(PunchIn as time))<0 then (select #start='09:30:00.0000000') end
from TimeTracker
This is not the full SQL but you can see the logic I am trying to employ. My question is how do I set the start time or end time based on value in another column such as punch in time or punch out time. SQL gives an error in the select statement as part of the when clause. I can do this easily in other languages but getting stumped in SQL.
You were almost there!
Below is your modified SQL code. See https://learn.microsoft.com/en-us/sql/t-sql/language-elements/case-transact-sql for the full syntax of CASE stmt.
declare #start time;
declare #end time;
select #start=cast('09:30:00.0000000' as time)
select #end=cast('17:30:00.0000000' as time)
SELECT Datename(dw,LastUpdate) as WeekDay
, FORMAT(PunchIn,'MM/dd/yyyy hh:mm tt') as PunchIn
, FORMAT(PunchOut,'MM/dd/yyyy hh:mm tt') as PunchOut
, Start = case
--employee punched in before 9:30 so take 9:30 as start time
when datediff(mi,#start,cast(PunchIn as time)) < 0 then #start
else cast(PunchIn as time)
end
, Stop = case
--employee punched out after 17:30 so take 17:30 as end time
when datediff(mi,#end,cast(PunchOut as time)) > 0 then #end
else cast(PunchOut as time)
end
from TimeTracker
NOTE: Your original code contained a reference to variable #start, which is not permitted. "A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations" (actual T-SQL error message). Therefore the solution posted will display result set that consists of five columns (Weekday, PunchIn, PunchOut, Start, Stop). If you were to use variables and more than one record was returned from the query, then only the last record would be saved in these variables! To store the entire set into another table, add additional line
into [table name]
before "FROM" keyword.
CASE statements are used to choose specific value expressions. There must be a specific value result for the statement. CASE statements are not if conditionals... they will not evaluate to executable code.
So instead of this:
--Bad
CASE WHEN 1=0 THEN Select #x=4+#y ELSE Select #x=2+#y END
You have to do things like this:
--Better
SELECT #x = CASE WHEN 1=0 THEN 4+#y ELSE 2+#y END
This shows you can still put some code in the expression, but it must still evaluate down to a value.
For the question here, it should look like more this:
case
--employee punched in before 9:30 so take 9:30 as start time
when datediff(mi,#start,cast(PunchIn as time))<0 then '09:30:00.0000000'
else PunchIn end
Though I still question doing an assignment in here.
This code is also interesting because, in most jurisdictions I've seen, it is highly illegal to alter PunchIn times like this. If an employee clocks in before they are supposed to that can be a disciplinary issue (management will ask them not to come in early, start writing them up, eventually fire them, etc), but until that process catches up the law says you must pay them for the time they worked. Again, this is jurisdictional, so consult a lawyer, but it sure looks like stealing time from workers.

t-SQL Selecting a records where an event happened today accounting for midnight and timezones

I have a table with a date column and time column and it gets populated whenever the user performs a scheduled task. They generally have a 2hr window to perform the task and I can't seem to get my mind around how to see if that task was done today or not.
For example, if it is 12:30 AM, I need to check whether it was done at 11:30 PM on the prior day, or at 12:01 AM today. I store all the time and dates as central time and have an offset number to adjust for other timezones.
Here is where I'm stuck, this works for something done last night, but not if it was done today after midnight (#DatePartOfDateTime is the date I am checking (it has already been corrected for timezone) and #EndTime is the time I am checking to see if it happened):
select 1 from tblMedsDispensed
where DatePassed =
case when (#EndTime = '23:59' or #Offset < 0 and #EndTime < '21:59')
and TimePassed < '01:00'
-- For midnight, if the time passed is < 01:00 then roll it back a day
then dateadd(DAY,1,#DatePartOfDateTime )
else #DatePartOfDateTime end
and tblMedsDispensed.patdrugs_fk = tblPatDrugs.PatDrugs_id
Any ideas?
Here's a guess. I don't think you need to mess around with all those variables and time components. What you want to do is sort of rotate the clock so that your logical start of day lines up with a calendar day so the date comparisons are easy.
select *
from tblMedsDispensed
where
cast(dateadd(hh, #Offset - 1, DatePassed) as date) = cast('<literal date>' as date)
EDIT: I looked over your question again and I see you've got two columns. The idea here is the adjust the date value backward one day when the hour component is less than 1. I'm still not clear whether your tolerance is one hour or two hours.
dateadd(
hh,
case when hour(dateadd(hh, #Offset, <TimeColumn>)) < 1 then -1 else 0 end,
<DateColumn>
)

Resources