Equivalent SSIS expression - sql-server

I am unable to convert the following SQL to a corresponding SSIS expression
and cast it to DATE format
SUBSTRING(A.FILENAME,13,2)+'-'+SUBSTRING(A.FILENAME,15,2)+'-'+SUBSTRING(A.FILENAME,17,4)
This is the best I could get
DT_DATE(SUBSTRING(#[User::V_LoadFileName],13,2)+'-'+SUBSTRING(#[User::V_LoadFileName],15,2)+''+SUBSTRING(#[User::V_LoadFileName],17,4))
Any suggestions?

String to cast to Date in SSIS has to be YYYY-MM-DD.
If you want to cast String to Datetime, it should be YYYY-MM-DD HH:MIS:SS.

The reasoning for the formatted data in Ferdipux's answer is that your environment may not be using the same style of DATE (i.e. YYYY/MM/DD vs YYYY/DD/MM).
Also, your example has syntax problems. Casting in SSIS is a little odd. You close your parenthesis BEFORE the variable.
(DT_BOOL)"0" returns FALSE
Note also the use of TWO quotations in SSIS. So you will likely need to use '"' in your script to work.
Some examples of casting in SSIS:
( «type» ) «expression»
(DT_I4)
(DT_STR, «length», «codepage» )
(DT_DATE)
(DT_BOOL)
(DT_WSTR, «length» )
(DT_NUMERIC, «precision», «scale» )
(DT_DECIMAL, «scale» )
(DT_DBTIMESTAMP)
Lastly, if you can, use the Expression Tester. Made life REALLY easy for me in designing my own SSIS packages. :D
http://expressioneditor.codeplex.com/

Related

SQL Server appears to correctly interpret non-supported string literal formats

Have an instance of SQL Server 2012 that appears to correctly interpret string literal dates whose formats are not listed in the docs (though note these docs are for SQL Server 2017).
Eg. I have a TSV with a column of dates of the format %d-%b-%y (see https://devhints.io/datetime#date-1) which looks like "25-FEB-93". However, this throws type errors when trying to copy the data into the SQL Server table (via mssql-tools bcp binary). Yet, when testing on another table in SQL Server, I can do something like...
select top 10 * from account where BIRTHDATE > '25-FEB-93'
without any errors. All this, even though the given format is not listed in the docs for acceptable date formats and it apparently also can't be used as a castable string literal when writing in new records. Can anyone explain what is going on here?
the given format is not listed in the docs for acceptable date formats
That means it's not supported, and does not have documented behavior. There's lots of strings that under certain regional settings will convert due to quirks in the parsing implementation.
It's a performance-critical code path, and so the string formats are not rigorously validated on conversion. You're expected to ensure that the strings are in a supported format.
So you may need to load the column as a varchar(n) and then convert it. eg
declare #v varchar(200) = '25-FEB-93'
select convert(datetime,replace(#v,'-',' '),6)
Per the docs format 6 is dd mon YY, but note that this conversion "works" without replacing the - with , but that's an example of the behavior you observed.

OLE DB Source in Data Flow Issue with Variable

I’m experiencing a frustrating issue when trying to call a proc in an OLE DB source task. I’m using the SQL command from variable data access mode but I can see that it isn’t evaluating my variable correctly.
My variable (with ValidateAsExpression set to True) uses an expression to create a sql command like “EXEC ProcName ‘Param'” where the value of Param comes from a variable who’s value I set using an EXEC SQL task. Below is the expression:
“EXEC ProcName ” + “‘” + #[User::vDateThreshold] + “‘”
If I use a variable in my source that references a static value it works fine, but the issue seems to be when I use a variable which reference another variable in its expression.
Has anyone else come across this issue?
I’m using this method because I’ve had a similar issue when trying to use a parameter with the sql command data access method.
Thanks in advance
I’m using this method because I’ve had a similar issue when trying to use a parameter with the sql command data access method.
The right way to do that is by using SQL Command with parameters:
EXEC ProcName ?
And select #[User::vDateThreshold] as parameter.
Parameterized OLEDB source query
If it is not working then check your procedure code and make sure it generate a specific result set. If the result set is dynamic and columns are not fixed then you have to define it in the query using WITH RESULTSETS keyword.
https://www.mssqltips.com/sqlservertip/2356/overview-of-with-result-sets-feature-of-sql-server-2012/
From the name of #[User::vDateThreshold it seems like an SSIS datetime variable. Try setting this to a variable with an explicit cast and then executing the stored procedure with the variable. Make sure there that are single quotes (') within the CAST function as you would use if this was done in SSMS. When concatenating a datetime variable within a string variable in SSIS, the datetime variable must be converted to text, which is done with (DT_STR, length, codepage) in the sample expression below. I'm not sure what version you're using, but testing this out on SSDT for Visual 2017 worked fine for me. This will cover if you still want to hold the SQL in a variable, however the solution that #Hadi posted is a good option if you'd prefer to go that route.
"DECLARE #pDate DATETIME
SET #pDate = CAST('" + (DT_STR, 50, 1252)#[User::vDateThreshold] + "' AS DATETIME)
EXEC ProcName #pDate"
Thank you for the responses to my question.
I actually found the issue was with the ordering of my tasks in the package. When I looked closer at the values assigned to the relevant variables by using a break point on my exec SQL task I could see the wrong date was being passed to my proc. When I set the value of vDateThreshold at an earlier point the correct date value was assigned.
I think this was a case of looking at something for long enough that I was missing the obvious.

SQL Server Concatenation of Different Data Types

Is it possible to concatenate different data types in T-SQL that does not require to convert everything to the same data type?
Below code show the scenario:
DECLARE #weight INT = 50
PRINT 'The weight is' + #weight + 'years old'
Depends how you concatenate, if you use + you'll need an explicit conversion, but you can use the concat function and it'll implicitly convert the parameters for you. Having said that doing things explicitly is very often a good idea.
If you are using version < SQL Server 2012 , you have only one option which is to +. In this case, you are left with no other option than explicit conversion.
But, with the versions starting from SQL Server 2012 you can use CONCAT which does implicit conversions for you.

Subtract Operator in Stored Proc for Concatenate

I am getting the data type error in my stored procedure because I'm using Field1+'-'+Field2. I tried a convert and a cast, but it's not liking the syntax I used for that pesky -.
For the subtraction operation, what's the best way to use it as a hyphen or dash instead of an operator?
Thank you!!!
You need to convert both field to strings, like this:
Convert(VarChar(10), Field1) + '-' + Convert(VarChar(10), Field2)
If either field is a number, sql server will treat this as a math operation instead of concatenation.
** I used varchar(10) as an example. You should double check your data types and adjust the 10 accordingly.
If you are on 2012+
CONCAT(Field1,'-',Field2)
is a bit less verbose. Docs
All arguments are implicitly converted to string types and then
concatenated. Null values are implicitly converted to an empty string

A 99.99 numeric from flat file doesn't want to go in a NUMERIC(4,2)'SQL Server

I have a csv file :
1|1.25
2|23.56
3|58.99
I want to put this value in a SQL Server table with SSIS.
I have created my table :
CREATE TABLE myTable( ID int, Value numeric(4,2));
My problem is that I have to create a Derived Column Transformation to specify my cast :
(DT_NUMERIC,4,2)(REPLACE(Value,".",","))
Otherwise, SSIS don't seem to be able to put my Value in my column, and fill my column with null value.
And I think it is tooooo ugly to do it this way. I want my Derived Column Transformation be here for real new derived column, and not some simple cast that I think SSIS have to detect.
So, what is the standard way to use SSIS to resolve this problem ?
BULK
INSERT myTable
FROM 'c:\csvtest1.txt'
WITH
(
FIELDTERMINATOR = '|',
ROWTERMINATOR = '\n'
)
csvtest1.txt
1|1.25
2|23.56
3|58.99
You're loading this up in international format (56,99 in lieu of 56.99). You need to load this as 56.99 for SQL Server to recognize it as such. Take out the REPLACE(Value, ".", ",") and just have the code be:
(DT_NUMERIC,4,2)(Value)
Handle the formatting on the application side, not on the data side. The comma is a reserved operator in SQL Server and you can't change that fact.
Haven't used SSIS a whole lot, but can't you set the regional settings on the File Source or at least set the decimal separator?
Can you change your SSIS source column to be in the correct datatype?
If you have control over the production of your file, I'd suggest you to format values without ANY decimal or thousand separation : in this case I'ld have a file with values:
1|125
2|2356
3|5899
and then apply a division by 100 when importing the data. While it has the advantage of being culture-independent, of course it has some drawbacks:
1) First of all, it may not be possible to impose this format of the file.
2) It presumes that all numeric values are formatted accordingly, in this case every value is multiplied by 100; this can be an issue if you have to mix values from countries with different decimal positions (many have two decimals, but some have zero decimals).
3) It may severely impact with other routines, maybe out of your control
Therefore, this can really be an option if you have total control on the csv file.

Resources