SSIS Variable Changing Time Component - sql-server

I have a SSIS Variable named "DestinationDirectory" that has the following Expression:
#[User::SourceDirectory] + "\\" + REPLACE(SUBSTRING((DT_WSTR,35)((DT_DBTIMESTAMPOFFSET, 7) GETDATE() ),1,19),":","")
It returns for example:
C:\Finance Extract\2018-11-10 125913
I then have a heap of other variables such as the one below named "DestinationFileAdjustment" that work off "DestinationDirectory". It has the following expression:
#[User::DestinationDirectory]
+ "\\Adjustment_"
+ RIGHT("0" + (DT_STR, 2, 1252) DATEPART("dd" , GETDATE()), 2)
+ "_"
+ RIGHT("0" + (DT_STR, 2, 1252) DATEPART("mm" , GETDATE()), 2)
+ "_"
+ (DT_STR, 4, 1252) DATEPART("yyyy" , GETDATE())
+ ".csv"
What is supposed to happen is a file be created within that directory. The problem I'm experiencing is each time #DestinationDirectory is referred to, it is returning a different time value (e.g. C:\Finance Extract\2018-11-10 125914) and errors out because the directory does not exist.
Is there a way I can set that variable at run-time and it retain the same time value each and every time it is referred to?

Since you're using GETDATE() in your expression, I'm guessing that you're using the time that the package begins in the "DestinationDirectory" variable? If so, using the #[System::StartTime] system variable for the expression in this variable (example below) will provide this time and be consistent throughout the execution of the package.
#[User::SourceDirectory] + "\\" + REPLACE(SUBSTRING((DT_WSTR,35)((DT_DBTIMESTAMPOFFSET, 7) #[System::StartTime]),1,19),":","")

What I finished up doing to get around this was to have a Script Task and the following code within it:
Dts.Variables("User::DestinationDirectory").Value = Dts.Variables("User::SourceDirectory").Value.ToString + "\\" + Replace(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), ":", "")
That hard coded the value for the variable nicely.

Related

SSIS For Loop - Increment 'YYYYMM' by Month in Loop

I am trying to execute a for loop that passes a begin date in the format like '201812' and goes up increments to an end date (as an example) of '201903'. The variables get passed as Integers to stored procs which then grab and insert data based on those values. I was trying to implement the pattern found here but it does not seem to be correctly incrementing:
SSIS For Loop Container with Date Variable
I have set up variables as follows:
The ETLBeginPeriod and ETLEndPeriod are set in Execute SQL Tasks here:
And then here are the expressions in the For Loop
The full expression in the AssignExpression is
#[User::Counter] = LEFT((DT_WSTR,19)(DATEADD("mm",1,(DT_DBDATE)(LEFT((DT_WSTR, 10) (#[User::Counter]),4) + "-" + RIGHT((DT_WSTR, 10) (#[User::Counter]),2) + "-" + "01"))),4) + SUBSTRING((DT_WSTR,19)(DATEADD("mm",1,(DT_DBDATE)(LEFT((DT_WSTR, 10) (#[User::Counter]),4) + "-" + RIGHT((DT_WSTR, 10) (#[User::Counter]),2) + "-" + "01"))),6,2)
When testing the AssignExpression the expression itself does return a correct value (i.e. it will change 201808 to 201809 but this doesn't seem to be getting hit. It will get the correct value on the initial pass and run 201808 and then try again with 201808. So it doesn't seem to change the Counter Value.
I think the main issue is that you forgot to cast the whole result as integer. Try using the following expression:
#[User::Counter] = (DT_I4)(LEFT((DT_WSTR,19)(DATEADD("mm",1,(DT_DBDATE)(LEFT((DT_WSTR, 10) (#[User::Counter]),4) + "-" + RIGHT((DT_WSTR, 10) (#[User::Counter]),2) + "-" + "01"))),4) + SUBSTRING((DT_WSTR,19)(DATEADD("mm",1,(DT_DBDATE)(LEFT((DT_WSTR, 10) (#[User::Counter]),4) + "-" + RIGHT((DT_WSTR, 10) (#[User::Counter]),2) + "-" + "01"))),6,2))
I figured this out - I decided to add a script task to view the variables and it turns out that they were incrementing correctly, but I had the wrong variable assigned to get passed to the stored procedure. I had originally been using the ETLBeginPeriod and forgot to change it to the Counter variable. Once I did that it worked. Arg.

Change date format M/d/yyy hh:mm:ss to yyyy-MM-dd using expression

Hi I have one doubt in ssis
I want change date format M/d/yyy hh:mm:ss to yyyy-MM-dd using ssis expression and DateFormat variable datatype is string and getting format like 5/28/2019 12:00:00 AM. Data comes like below:
5/28/2019 12:00:00 AM
Based on above values i want output in other variable
2019-05-28
I tried like expression
(DT_STR, 4, 1252) DATEPART("yy" , #[User::DateFormat]) + "-" +
RIGHT("0" + (DT_STR, 2, 1252) DATEPART("mm" , #[User::DateFormat]), 2) +
"-" + RIGHT("0" + (DT_STR, 2, 1252) DATEPART("dd" , #[User::DateFormat]), 2)
but getting error like below :
ADDITIONAL INFORMATION:
The function "YEAR" does not support the data type "DT_WSTR" for
parameter number 1. The type of the parameter could not be implicitly
cast into a compatible type for the function. To perform this
operation, the operand needs to be explicitly cast with a cast
operator.
Evaluating function "YEAR" failed with error code 0xC0047089.
The function "YEAR" does not support the data type "DT_WSTR" for
parameter number 1. The type of the parameter could not be implicitly
cast into a compatible type for the function. To perform this
operation, the operand needs to be explicitly cast with a cast
operator.
can you please tell me how to write expression to achive this task in ssis
The main error is that #[User::DateFormat] variable is a string variable while DATEPART() function can be only applied to a date time value. (Even if the string variable stores a date time value)
You can benefit from TOKEN() function to achieve that:
TOKEN(TOKEN( #[User::DateFormat],"/",3)," ",1) + "-" +
RIGHT("0" + TOKEN( #[User::DateFormat],"/",2),2) + "-" +
RIGHT("0" + TOKEN( #[User::DateFormat],"/",1) ,2)
I have added type casts for date.
This would help
(DT_WSTR, 4) YEAR( (DT_DATE) #[User::Variable] ) + "-" + RIGHT("0"+(DT_WSTR,2) MONTH( (DT_DATE) #[User::Variable] ),2) + "-" + RIGHT("0"+(DT_WSTR, 2) DAY( (DT_DATE) #[User::Variable] ),2)
Create a new variable in your SSIS package with data type String and use the datetime field(here as #[User::Variable]) coming in your input in that variable as in below expression:
(DT_WSTR, 4) YEAR( #[User::Variable] ) + "-" +
RIGHT("0"+(DT_WSTR,2) MONTH( #[User::Variable] ),2) + "-" +
RIGHT("0"+(DT_WSTR, 2) DAY( #[User::Variable] ),2)
You can convert this string variable into date type later on if required.

Cast (DT_TIMESTAMP) is not consistent from String to DateTime

I'm trying to convert an input of DT_WSTR to DT_TIMESTAMP on SSIS Derived column and when I do it the values do not match up, on one ocasion it recognizes the year correctly but on the other it think the day is the year
I tried to do
(DT_TIMESTAMP)((DT_WSTR,4)YEAR([Data Hora]) + RIGHT("0" + (DT_WSTR,2)MONTH([Data Hora]),2) + RIGHT("0" + (DT_WSTR,2)DAY([Data Hora]),2) + (DT_WSTR,10) Time_Column)
with no success
08-04-19 15:31:27 this is what I input and sometimes it recognizes the 19 as 2019 correctly but other times it thinks the 08 is the year so it puts 19/04/2008, I want the first one.
I expect to get the date correctly in dd/mm/yyyy hh:MM:ss.
Your question is not clear. In this answer I will try to fix the provided expression. Try using the following expression:
(DT_DBTIMESTAMP)((DT_WSTR,4)YEAR([Data Hora]) + "-" +
RIGHT("0" + (DT_WSTR,2)MONTH([Data Hora]),2) + "-" +
RIGHT("0" + (DT_WSTR,2)DAY([Data Hora]),2) + " " +
(DT_WSTR,10) [Time_Column])
Another suggestion is that, in cases where the date format is tricky (2 digit year part), it is better to use a script component to parse the date value since it provides more options using Date.ParseExact() function, as example:
Row.outDateColumn = DateTime.ParseExact(Row.inStringDate,"dd-MM-yy HH:mm:ss",System.Globalization.CultureInfo.InvariantCulture);

Convert GETDATE() to YYYYMMDDhhmmss as derived column

I'm trying to convert getdate to a string in YYYYMMDDHHmmss format without much luck. I need to do this in SSIS as a derived column.
I've tried using Datepart, but it's not working.
Datepart("YYYY",(GETDATE())) & datepart("MM",MONTH(GETDATE())) & DATEPART("DD",(GETDATE())) & DATEPART("HH",(GETDATE()) & DATEPART("MM",(GETDATE())) & DATEPART("SS",(GETDATE()))
Any clues what I'm doing wrong?
Try this:
(DT_STR,4,1252)DATEPART( "yyyy" , getdate() ) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "mm" , getdate() ), 2) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "dd" , getdate() ), 2) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "Hh" , getdate() ), 2) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "mi" , getdate() ), 2) +
RIGHT("0" + (DT_STR,4,1252)DATEPART( "ss" , getdate() ), 2)
This should do it, it simply casts GETDATE() as a string and replaces unnecessary characters.
LEFT(REPLACE(REPLACE(REPLACE((DT_STR,30,1252)GETDATE(),"-",""),":","")," ",""),14)
DATEPART
Returns an integer representing a datepart of a date.
The operation you would like to do is string concatenation for those values. The operator for string concatenation in the SSIS Expression language is +. However, + is also the addition operator for the integer data type so if you use
Datepart("YYYY",(GETDATE())) + datepart("MM",MONTH(GETDATE()))
You would not get 201410. Instead, you'd have a value of 2024. Now, you can use addition to get you were you want to be, you'll just need multiplication as well. (2014 * 100) + 10 will equal 201410 and returns the value as integer so perhaps that fits with what you want. However, once you build out to YYYYMMDDHHMMSS you're probably outside the bounds of Int32 and I'm too lazy to look it up, possibly Int64.
The better approach will be to cast the results of the DatePart to a string and use concatenation. But, there's still a problem there. 05 as an integer is just 5. That leading zero is an artifact of presentation so if you want it in your value, you'll need to explicitly put it there. The preferred method of doing so is to concatenate a leading 0 and then shave off the last 2 characters. For October-December, you'll have a 3 character string 010/011/012 that then gets turned back into 10/11/12. The remaining months will become 01/02/../09 and taking the right two most characters yields the correct values.
RIGHT(("0" +(DT_WSTR, 2) MONTH(GETDATE())), 2)
The & isn't a concatenation operator in this languages so that is problem #1 with your formula.
Here's what worked for me.
(DT_STR, 4, 1252)DATEPART("YYYY", GETDATE())+(DT_STR,2,1252)DATEPART("MM", GETDATE())+(DT_STR,2,1252)DATEPART("DD", GETDATE())+(DT_STR,2,1252)DATEPART("HH", GETDATE())+(DT_STR,2,1252)DATEPART("MI", GETDATE())+(DT_STR,2,1252)DATEPART("SS", GETDATE())
This should give you what you want:
REPLACE(REPLACE(REPLACE(CONVERT(varchar, GETDATE(), 20), '-', ''), ':', ''), ' ', '')
See here for more date formats you can use with convert

Leading Zero with Datestamp in SSIS Expression

I'm trying to format a datestamp to have leading zeros in an expression using SSIS 2008 R2.
My desired result would be Exceptions - YYYYMMDDHHMMSS.xls so as an example, now would be:
\\SomePath\Exceptions - 20150211155745.xls
I am having an issue adding the leading zeros to the day and month though.
I've tried the following expressions by trying to convert to DT_WSTR with the length set as well as picking the date apart usg SUBSTRING:
#[User::XLFileRootDir] + "Exceptions - " + (DT_WSTR, 4) DATEPART("YYYY", GETDATE()) + (DT_WSTR, 2) DATEPART("MM", GETDATE()) + (DT_WSTR, 2) DATEPART("DD", GETDATE()) + ".xls"
This results in \\SomePath\Exceptions - 2015211155745.xls (notice the missing leading zero on the month).
#[User::XLFileRootDir] + "Exceptions - " + (DT_WSTR, 4) SUBSTRING(GETDATE(), 1, 4) + ".xls"
This results in an error as the data type DT_DBTIMESTAMP isn't supported by the function SUBSTRING. I'm aware that some sort of conversion needs to take place but can't find a function within SSIS to complete this.
Could anyone help me with how to format the expression with leading zeros?
The problem you're running into is that the YEAR/MONTH/DAY functions return an integer. An integer won't present leading zeros. Therefore, the "trick" is to convert it to a string. Prepend a leading zero to that string. Then, shear off the last 2 characters using the RIGHT function. The trimming is only required for October, November, and December but the logic is cleaner to unconditionally apply RIGHT.
This builds your YYYYMMDD string.
(DT_WSTR, 4)YEAR(#[System::StartTime])
+ RIGHT("0" + (DT_WSTR, 2) MONTH(#[System::StartTime]), 2)
+ RIGHT("0" + (DT_WSTR, 2) DAY(#[System::StartTime]), 2)
I find it better to use the variable System::StartTime rather than GETDATE(), especially when time is involved. GETDATE will be evaluated each time it is inspected. Over long running packages, there can be a sizable drift in the values returned. System::StartTime is the time the package itself began. It is constant for the run itself but obviously resets per run.
For my application, I needed the exact current time, and I needed it down to the second, which yielded this:
(DT_WSTR, 4)DATEPART("yyyy",GETDATE())
+ RIGHT("0" + (DT_WSTR, 2) DATEPART("mm",GETDATE()),2)
+ RIGHT("0" + (DT_WSTR, 2) DATEPART("dd",GETDATE()),2)
+ RIGHT("0" + (DT_WSTR, 2) DATEPART("Hh",GETDATE()),2)
+ RIGHT("0" + (DT_WSTR, 2) DATEPART("mi",GETDATE()),2)
+ RIGHT("0" + (DT_WSTR, 2) DATEPART("s",GETDATE()),2)
SUBSTRING((DT_WSTR, 29) GETDATE(), 6, 2)

Resources