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))
Related
Is it possible to override the value of a variable in a SSIS package, which is calculated via an expression, by passing in a different value on the DTExec command line?
I have a parameterized query and I'm passing variable User::StartDate into it. The package name is OpenAirExport.dtsx.
If I invoke my package using DTExec from PowerShell I can set the StartDate variable fine on the command line. For example:
& "C:\Program Files\Microsoft SQL Server\150\DTS\Binn\DTExec.exe" -File 'OpenAirExport.dtsx' `
-Set '\Package.Variables[User::StartDate].Properties[Value];2020-09-22'
This works fine. I can see from the resulting data that the start date was indeed set to 22 Sep 2020.
99% of the time, though, the package will just be getting the previous day's data. So I set an expression on the StartDate variable to calculate its value:
DATEADD("day", DATEDIFF("day", (DT_DBTIMESTAMP)0, GETDATE()) - 1, (DT_DBTIMESTAMP)0)
(This rather complicated looking expression just counts the number of days since day 0 then adds them to day 0 and subtracts 1. This is a fairly standard way in SQL Server of stripping the time from a datetime, leaving just the date. In this case it will give a datetime of 00:00 hours yesterday)
Now if I call the package using DTExec from PowerShell without setting the StartDate variable value it gives the correct result - data from yesterday.
Every now and again a downstream process fails and we're asked to re-run a previous day's data. So I want to be able to override the calculated value for StartDate with a value passed in from the command line. But I find that if I try to set the value from the command line this value gets ignored and the expression is still used to calculate StartDate.
Is there any way I can force SSIS to override the expression value with a value passed in from the command line?
You are overriding it. The problem is, that en expression is evaluated every time you read/use it so the package starts up, you specify what the value should be and then when a task/component goes to use the value, the execution engine says "Oh, StartDate has an expression on it. Let's evaluate it in case the value has changed"
A easier option would be to remove the expression altogether from #StartDate. Set to the minimum (or maximum) date value which should never do anything if the package is run outside of the standard mechanism of your Posh script. With the fail safe in place, you have your standard start of
-Set '\Package.Variables[User::StartDate].Properties[Value];$RunDate'
where $RunDate was calculated beforehand.
$RunDate = Get-Date -Format "yyyy-MM-dd"
# If we need to manually adjust start date, uncomment this line and use the right date
# $RunDate = "2020-09-22"
When the downstream system fails, you explicitly change the value and patch in the assignment so it gets used.
I was able to do it by making the following modifications:
Get rid of the expressions set for variables StartDate and EndDate. Initially I left the values blank but after saving and reopening the package I found SSIS had defaulted the values to 30 Dec 1899. Very weird date (why not 31 Dec 1899, or even 1 Jan 1900 corresponding to the 0 date for the SQL Server DATETIME data type?). However, some Googling showed me others have found SSIS uses the same default date. So it wasn't something I somehow set by accident;
In the OLE DB Source for the SSIS package I modified the SQL Command code that received the incoming parameters. Previously it was:
DECLARE #StartDateTime DATETIME = ?;
DECLARE #EndDateTime DATETIME = ?;
I changed it to:
DECLARE #DefaultDateTime DATETIME = '1899-12-30';
DECLARE #StartDateParameter DATETIME = ?;
DECLARE #StartDateTime DATETIME = #StartDateParameter;
IF COALESCE(#StartDateParameter, #DefaultDateTime) = #DefaultDateTime
BEGIN;
-- Default to 00:00 hours yesterday.
SET #StartDateTime = DATEADD(day, DATEDIFF(day, 0, GETDATE()) - 1, 0);
END;
DECLARE #EndDateParameter DATETIME = ?;
DECLARE #EndDateTime DATETIME = #EndDateParameter;
IF COALESCE(#EndDateParameter, #DefaultDateTime) = #DefaultDateTime
BEGIN;
-- Default to 1 day after start date.
SET #EndDateTime = DATEADD(day, 1, #StartDateTime);
END;
Following these modifications the package would run if I didn't explicitly set the StartDate and EndDate variables on the command line. The #StartDateTime in the SQL query would default to 00:00 hours yesterday, and the #EndDateTime in the query would default to a day later, 00:00 hours this morning.
If I did explicitly set the StartDate and/or EndDate variables on the command line the #StartDateTime and the #EndDateTime in the SQL query would be set to the StartDate and/or EndDate variable values.
I have a Stored Procedure that will run within a time period (between 2-3 am), but not always at the exact same time during that period.
As part of this procedure I need to do 3 steps:
1: Get the start of yesterday's date
So if today is 13/08/2020 13:51:02 I need the query to return 12/08/2020 00:00:00 and do this dynamically
2: Get the end of yesterday's date
In the above this would return 12/08/2020 23:59:59
3: Convert both values into Unix EPOCH timestamps
I have used in the past on a similar issue (that was less time-sensitive) the below bit of Code:
declare #yesterday date
set #yesterday = (SELECT convert(datetime, DATEADD(day, -1 ,getdate()), 23 ))
The Problem here is that this gives a value that is exactly 24 hours in the past, so if the SP is run at 2:15 am - it's time stamp will be different when it's run at 2:23 am or 2:53 am.
Once I've got a method of getting the start and end date to always be correct - I'll then use something like this solution to convert the Datetime into Epoch timestamps, unless someone who answers this question has a snazzy method of doing it all in one (for which I would be eternally grateful)
To get midnight yesterday, do this:
DECLARE #yesterday DATETIME
= DATEADD(DAY, -1, CAST(GETDATE() AS DATE));
To get midnight today do
DECLARE #today DATETIME = CAST(GETDATE() AS DATE);
To filter for times that happened yesterday, do
WHERE ts >= #yesterday AND ts < #today ...
The CAST operation truncates the date/time value returned by GETDATE() to midnight.
The form of WHERE with >= and < copes with the edge case correctly. It also happens to exploit an index on the column I called ts.
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
I have a question about converting UTC time zone to EST time zone since I am still new to SQL language and Azure platform. In log file, I used system built-in function "GetDate()" in log file to get the Date/Time. However, while accessing Azure database on my SSMS, using system-built in function (GetDate()) gives me the datetime in UTC time zone, which is 4 hours ahead of Eastern Time Zone (EST). I have asked similar question before for converting UTC to EST here
, and #DanGuzman helped me fix my code. But this question is more about converting UTC to EST (considering Daylight saving time dynamically). Below is my code so far, and I used this link as a reference. However, I would like to make my code dynamic so that I can keep using it for 2020, 2021 as well.
Below code works ONLY for 2019 (since Daylight Saving starts on March 10,2019 until November 3, 2019. Within the date range, below code forward one hour of EST time during daylight saving time range.
CREATE FUNCTION [dbo].[EST_GetDateTime]
(
-- no parameter
)
RETURNS datetime
AS
BEGIN
DECLARE
#EST datetime,
#StandardOffset int,
#DST datetime, -- Daylight Saving Time
#SSM datetime, -- Second Sunday in March
#FSN datetime -- First Sunday in November
-- get DST Range
set #EST = CAST(DATEADD(hh,-5,GETDATE()) AS DATETIME)
set #StandardOffset = 0
set #SSM = datename(year,#EST) + '0310' -- Set which day daylight saving start (for 2019, March 10)
set #SSM = dateadd(hour,2,dateadd(day,datepart(dw,#SSM)*-1+1,#SSM))
set #FSN = datename(year,#EST) + '1103' -- Set which day daylight saving start (for 2019, March 10)
set #FSN = dateadd(second,-1,dateadd(hour,2,dateadd(day,datepart(dw,#FSN)*-1+1,#FSN)))
-- add an hour to #StandardOffset if #EST is in DST range
if #EST between #SSM and #FSN
set #StandardOffset = #StandardOffset + 1
-- convert to DST
set #EST = CAST(DATEADD(hh,-5+#StandardOffset ,GETDATE()) AS DATETIME)
RETURN #EST
END
GO
Can someone please give any suggestions how to improve my existing code (able to work dynamically) so that I do not need to change the function every single year for adjusting day light saving.
Since Azure SQL is ahead of the on-premises version, I think you can use the syntax select getutcdate() at time zone 'UTC' at time zone 'Eastern Standard Time'. Also, I'd switch to getutcdate() as that should be invariant regardless of the server's TZ. More information on at time zone here.
One method is a function that converts SYSDATETIMEOFFSET() to EST and converts the result to datetime:
CREATE FUNCTION dbo.EST_GetDateTime()
RETURNS datetime
AS
BEGIN
RETURN(SELECT CAST(SYSDATETIMEOFFSET() AT TIME ZONE 'Eastern Standard Time' AS datetime));
END
GO
--example usage
SELECT dbo.EST_GetDateTime();
GO
This should do exactly what you need.
SELECT CONVERT(DATETIME,GETDATE() AT TIME ZONE (SELECT CURRENT_TIMEZONE_ID()) AT TIME ZONE 'Eastern Standard Time')
Explanation: This gets the current datetime in the server's local timezone using CURRENT_TIMEZONE_ID(). We then use AT TIME ZONE to make it a datetimeoffset, then we cut that datetimeoffset over to requested timezone... here 'Eastern Standard Time'. Lastly the whole thing is wrapped in a CONVERT() to cut the datetimeoffset objects over to a proper datetime datatype.
Store PROCEDURE
--para--
#StartingDate DateTime = NULL,
#EndingDate DateTime = NULL
--condition --
dbo.callentry.CallDateTime BETWEEN ISNULL(#StartingDate,
dbo.callentry.CallDateTime) and ISNULL(#EndingDate,dbo.callentry.CallDateTime)
Question :
when i pass date '2012-09-17' from date picker as para #StartingDate, and the same as ending date . it is comparing 2012-09-17 00:00:00.000 to 2012-09-17 00:00:00.000 - will return no records
what i want is records in whole day 2012-09-17
Why not just use #StartingDate-1 then?
Or even DATEADD(d,-1,#StartingDate)
Or #EndDate + 1
Or even DATEADD(d,1,#EndDate)
DATEADD (Transact-SQL)
Returns a specified date with the specified number interval (signed
integer) added to a specified datepart of that date.
Try this:
dbo.callentry.CallDateTime >=ISNULL(#StartingDate,
dbo.callentry.CallDateTime) and dbo.callentry.CallDateTime <=ISNULL(#EndingDate,dbo.callentry.CallDateTime)
Also make sure dbo.callentry.CallDateTime this column datatype is also datetime
OR
Also reading from your question. I think when strt and end date are same you just need all the records for that day. if start and end date are same why cant you just use like below:
convert(date,dbo.callentry.CallDateTime) =convert(date,ISNULL(#StartingDate,
dbo.callentry.CallDateTime))
In case of sql server 2008 if below just convert both the sides to just date format annd compare