IsWeekEnd Expresion in SSIS that is locale-neutral - ssis

How can I write an SSIS expression that determines whether a date is a weekend day?
I have this expression, but it seems it only 'works on my machine'
DATEPART( "Weekday", #[User::CurrentDate] ) ==6 || DATEPART( "Weekday", #[User::CurrentDate] ) ==7
After I deploy SSIS package to server, is suddenly changes order of numbers and
Monday became 2.
When on my computer Monday is 1, exactly as I expected.
I checked SQL Server itself, but it seems is something inside SSIS decide if Sunday or Monday is first day.
I cannot find exact question related to this issue.

Well, if you must do this in an SSIS expression, here is one way to work around the problem: you would compare the DW of your variable to the DW of a known constant (like August 3, 2019, which is a Saturday in any locale that I know of).
In pseudocode, IF ( DW(DateVariable) = DW("20190803") OR DW(DateVariable) = (DW("20190803")+1)%7 ) THEN {DateVariable is a weekend}
Personally, I would look for a way to do this in TSQL. Import the raw data "as is" into a staging table, and then do the transformation while moving the data to the destination table with a stored procedure.

DATEPART("DW",GETDATE()) or DATEPART("WEEKDAY",GETDATE()) works perfectly fine on both SQL server and local.
How are you passing value to #[User::CurrentDate] variable(Please check if same date is set when packages is executed on SQL server and on local)
I changed DateTime on my local and tested your expression as part Of Execute SQL task and Derived Column Transformation which gives me 1 for Sunday, 2 for Monday and so on and the result matches with SQL.
SQL query to get day of week:
SELECT GETDATE() Today,DATENAME("DW", GETDATE()) DayofWeekToday,
DATEPART("DW",GETDATE()) DayNumberToday,GETDATE()-1 Yesterday,
DATENAME("DW", GETDATE()-1) DayofWeekYesterday,DATEPART("DW",GETDATE()-1) DayNumberYesterday
Adding more to my answer : There is a difference between DateFirst and DatePart. DateFirst sets first day of the week while Datepart gives you day of the week. use this sql function to check what's your first day of the week
Set Datefirst 7 -- To set first day of week (7 = Sunday)
SELECT ##DATEFIRST -- To check first day of week
**Update your system settings to match first day of the week with sql server and you should get same values when you evaluate expression.
Your expression looks good its only your first day of week on local and sql server are not matching.
Once I updated first day of week on SQL, I was able to replicate the issue you are facing.

Related

Interesting SSRS parameter discovery when using subscriptions

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.

Expression Builder Date Assignment

I've built an SSIS package that runs on schedule weekly on Mondays. It looks for a .csv file that has a date at the end of the file name, which is 2 Saturdays ago from the date it runs (on Mondays). I need the variable to default to two Saturdays ago. Example: SSIS job runs on 7/9/2018, it needs to set it to 6/30/2018. SSIS needs to be runnable in case of failure, so if it has to be run again on, for example, 7/11/2018, it needs to default to 6/30/2018. This is a weekly job scheduled to run on Mondays.
I found a question posted similar to my need and the link is below for additional reference.
SSIS expression previous date without DateAdd()
I just figured out how to format the date extension as 'mmddyyyy' inside Expression Builder for the variable. Below is my code.
RIGHT("0" + REPLACE((DT_WSTR, 30) (DT_DATE) DATEADD("Day", 7*(DATEDIFF("Day", (DT_DATE)0, GETDATE())/7-1), (DT_DATE)0),"/",""),8)

find the day example saturday from date in ssis

I want to find out the day of the week from date in ssis.
Actually i want to move the data from one server to another,
In the source server there is one cloumn reportdate having the previous date,so while i wan to copy in to the destination server wan to insert todays date,but there is one case like there is no data comes on sunday in the source server in that case i will have the data of saturday so in this case i want to update the date in the destination server with 2 days plus,please let me know how can i reslove this using ssis.i'm using derived column for manipulating the date column DATEADD("day",2,reportdate) : DATEADD("day",1,reportdate),
so first part will update the date plus 2 of the sourcedate into the detsination table date but how will i find the day of week means when the saturday comes...please let me know how can i reslove this using ssis.
Thanks is advance..
Try this :
DATENAME(weekday, GETDATE())== "Sunday" ? DATEADD("day",2,reportdate):
DATEADD("day",1,reportdate)
Use GETDATE() else use DATEADD(day,-1,reportdate) in the above expression
Update :
Use DATEPART in SSIS
DATEPART( "Weekday", getdate())
Expression is
DATEPART("weekday", GETDATE()) == 1 ? DATEADD("day",2,getdate()):DATEADD("day",1,getdate())
The above expression works in my system having SSIS 2008

How do I retry until a given date matches current date within For Loop Container?

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.

How to get time difference in VBScript

I have VB Script which is connected with the my database (SQL Server 2008), and this script query contains getdate() function, now I want to subtract 2 time value suppose SQL1-SQL2 and want only time difference, not the date.
SELECT DATEDIFF(MINUTE, SQL2, SQL1) FROM dbo.table;
If you want to do it in VBScript, then something like:
x = datediff("n", rs("SQL2"), rs("SQL1"))
T-SQL docs for datediff
VBScript docs for datediff