SSIS derived column error - ssis

I got this error while debugging in SSIS:
Error: 0xC0049064 at Data Flow Task, Derived Column [70]: An error occurred while attempting to perform a type cast.
Error: 0xC0209029 at Data Flow Task, Derived Column [70]: SSIS Error Code DTS_E_INDUCEDTRANSFORMFAILUREONERROR. The "component "Derived Column" (70)" failed because error code 0xC0049064 occurred, and the error row disposition on "output column "EVENT_DT" (118)" specifies failure on error. An error occurred on the specified object of the specified component. There may be error messages posted before this with more information about the failure.
Error: 0xC0047022 at Data Flow Task: SSIS Error Code DTS_E_PROCESSINPUTFAILED. The ProcessInput method on component "Derived Column" (70) failed with error code 0xC0209029. The identified component returned an error from the ProcessInput method. The error is specific to the component, but the error is fatal and will cause the Data Flow task to stop running. There may be error messages posted before this with more information about the failure.
Error: 0xC0047021 at Data Flow Task: SSIS Error Code DTS_E_THREADFAILED. Thread "WorkThread0" has exited with error code 0xC0209029. There may be error messages posted before this with more information on why the thread has exited.
Information: 0x40043008 at Data Flow Task, DTS.Pipeline: Post Execute phase is beginning.
Information: 0x40043009 at Data Flow Task, DTS.Pipeline: Cleanup phase is beginning.
Information: 0x4004300B at Data Flow Task, DTS.Pipeline: "component "DataReaderDest" (143)" wrote 0 rows.
Task failed: Data Flow Task
Warning: 0x80019002 at Package: SSIS Warning Code DTS_W_MAXIMUMERRORCOUNTREACHED. The Execution method succeeded, but the number of errors raised (4) reached the maximum allowed (1); resulting in failure. This occurs when the number of errors reaches the number specified in MaximumErrorCount. Change the MaximumErrorCount or fix the errors.
SSIS package "Package.dtsx" finished: Failure.
My expression is:
(DT_DBTIMESTAMP)(SUBSTRING(EVENT_D,7,4) + "-" +
SUBSTRING(EVENT_D,4,2) + "-" +
SUBSTRING(EVENT_D,1,2) + EVENT_T)
My original data are in this sequence:
EVENT_D: DD/MM/YYYY
EVENT_T: HH:MM:SS
Any help are appreciated. I have try changing my expression numerous time but still fails.

I suspect that there are some date time values which are not in the correct format .So SSIS throws error while parsing them .
In order to find to incorrect date time value from your source table try to redirect the error rows from Derived Transformation and check the incorrect data using a data viewer
The problem with substring values are if the string data are not in the correct format then the Derived Transformation will throw error .
In your OLEDB source component try to write the sql and get only the correct datetime values
Ex:
Select col1,
case when isDate(EVENT_D) = 1 THEN EVENT_D ELSE NULL
END as [EVENT_D],
Col2,EVENT_T,other columns
from yourTable
in your derived transformations use your code to convert into DT_DBTIMESTAMP type .
Else Try to use a script component and parse the EVENT_D and EVENT_T values and convert to datetime values. No need to use Derived column with all those substring values
create a New Output column Valid_D with the datatype as DT_DBTIMESTAMP.Select the 2 input columns EVENT_D and EVENT_T in the available input Columns in Script Transformation Editor
VB.NET code
Dim result As DateTime
If DateTime.TryParseExact(Row.EVENT_D, "dd/MM/yyyy",
Nothing, Globalization.DateTimeStyles.None, result) Then
Row.ValidD = result.Add (TimeSpan .Parse (Row.EventT ) );
End If
C# code
DateTime result;
if (DateTime.TryParseExact(Row.EventD, "dd/MM/yyyy",
CultureInfo.InvariantCulture, DateTimeStyles.None,out result))
{
Row.ValidD = result.Add (TimeSpan .Parse (Row.EventT ) );
}
Now you can use Valid_D column which is of DateTime type in your subsequent transformations
Update : The problem with your syntax is you cannot add date+ time in the string format . You need to parse individually both EVENT_D and EVENT_T .
(DT_DBTIMESTAMP)(SUBSTRING(EVENT_D,7,4) + "-" +
SUBSTRING(EVENT_D,4,2) + "-" +
SUBSTRING(EVENT_D,1,2) + EVENT_T)
So your syntax is not valid.
The isDate function shows NULL for 30/04/2012 because as per MSDN
The return value of ISDATE depends on the settings set by
SET DATEFORMAT, SET LANGUAGE and Configure the default language
Server Configuration Option.
but it returns 1 for the value 01/05/2012 and 02/05/2012 because it takes as MM/dd/YYYY
so the 1st date is Jan 5th 2012 instead of May 1st 2012
So the soultion is use script component and parse these values into valid date and time and then use it in your subsequent transformations .
Please check my script transformation code above
Update 2:
I think your using SSIS 2005 .The code should be
Public Overrides Sub Input0_ProcessInputRow(ByVal Row As Input0Buffer)
Dim result As DateTime
If DateTime.TryParseExact(Row.EVENTD, "dd/MM/yyyy", Nothing, Globalization.DateTimeStyles.None, result) Then
Row.ValidD = result.Add(TimeSpan.Parse(Row.EVENTT))
End If
End Sub
after Script transformation ,you don't need to use Derived component .The result obtained in the column Valid_D contains the valid value which is of datetime format

If you wanted to do this without a script, you could have just changed your expression from
(DT_DBTIMESTAMP)(SUBSTRING(EVENT_D,7,4) + "-" +
SUBSTRING(EVENT_D,4,2) + "-" +
SUBSTRING(EVENT_D,1,2) + EVENT_T)
to
(DT_DBTIMESTAMP)(SUBSTRING(EVENT_D,7,4) + "-" +
SUBSTRING(EVENT_D,4,2) + "-" +
SUBSTRING(EVENT_D,1,2) + " " + EVENT_T)
Not having the space between the date and the time portions is what was most likely causing your original error. You were getting
2012-04-3012:25:37
instead of
2012-04-30 12:25:37

I faced the same problem while converting a string containing date to datetimestamp field. It is all due to spaces in the field.
So we need to check for space and then convert it to datetimestamp.
Below is the expression for the same.
LEN(TRIM([Field1])) == 1 ? NULL(DT_DBTIMESTAMP) : (DT_DBTIMESTAMP)(SUBSTRING([Field1],1,4) + "-" + SUBSTRING([Field1],5,2) + "-" + SUBSTRING([Field1],7,2) + " " + SUBSTRING([Field1],10,2) + ":" + SUBSTRING([Field1],12,2))

Related

SSIS Convert Blank Datetime column to NULL and Parse Input

I have the following simple SSIS Package to process a comma delimited file:
I'm having problems with date columns - specifically MoveInDate which the input column has data in the format '20090731000000'.
It goes into a database column MoveInDt which has a Datetime data type and data ends up in the format:
'2009-07-31 00:00:00.000'
In SSIS I have specified the input column to be DT_DBTIMESTAMP. I'm unable to figure out how to do a simple 'if MoveInDate is blank, load null, else change data to 'YYYY-MM-DD 00:00:00.000'
Right now I can't even seem to figure out how to load a hardcoded date
This fails
As does
"2019-01-01"
Or
(DT_DBTIMESTAMP)"2019-01-01"
(DT_DBTIMESTAMP)(DT_DATE)"2019-01-01"
Error: 0xC02020A1 at Data Flow Task, Flat File Source [11]: Data conversion failed. The data conversion for column "Move In Date" returned status value 2 and status text "The value could not be converted because of a potential loss of data.".
Error: 0xC0209029 at Data Flow Task, Flat File Source [11]:
Looking up that message I've found posts about the data types not matching on the input to output column, but looking at it ...
Checking the flat file input column, it is defined as DT_DBTIMESTAMP
And the destination column is also defined as DT_DBTIMESTAMP when looking at input output properties.
I've looked at many questions here and elsewhere and have tried reducing the input to one simple row in the input file. I've tried recreating the package several times.
If the data is stored in the following format in the flat file
20090731000000
Then leave the source column data type as DT_STR and add a dervied column with the following expression:
(ISNULL([MoveInDate]) || [MoveInDate] == "") ? NULL(DT_DBTIMESTAMP) :
(DT_DBTIMESTAMP)(LEFT([MoveInDate],4) + "-" +
SUBSTRING([MoveInDate],5,2) + "-" +
SUBSTRING([MoveInDate],7,2) + " " +
SUBSTRING([MoveInDate],9,2) + ":" +
SUBSTRING([MoveInDate],11,2) + ":" +
SUBSTRING([MoveInDate],13,2) )
If data is stored in the following format:
2009-07-31 00:00:00
Use the following expression:
(ISNULL([MoveInDate]) || [MoveInDate] == "")
? NULL(DT_DBTIMESTAMP)
: (DT_DBTIMESTAMP)[MoveInDate]
If data is stored in the following format:
2009-07-31
Use the following expression:
(ISNULL([MoveInDate]) || [MoveInDate] == "")
? NULL(DT_DBTIMESTAMP)
: (DT_DBTIMESTAMP)([MoveInDate] + " 00:00:00")

Catch SAPSQL_DATA_LOSS

I want to catch and handle SAPSQL_DATA_LOSS in my ABAP code.
I tried this:
try.
SELECT *
FROM (rtab_name) AS rtab
WHERE (sub_condition)
into table #<sub_result>
.
catch SAPSQL_DATA_LOSS into error.
...
endtry.
But above code is not valid. I get this message:
Type "SAPSQL_DATA_LOSS" is not valid
And I tried this:
catch SYSTEM-EXCEPTIONS SAPSQL_DATA_LOSS = 123.
SELECT *
...
.
endcatch.
if sy-subrc = 123.
...
endif.
But above code gives me:
Instead of "SAPSQL_DATA_LOSS" expected "system-exception" (translated from german to english by me)
How to catch SAPSQL_DATA_LOSS?
This question is not about "why does this exception happen?". This is already solved. My code should handle the exception.
SAPSQL_DATA_LOSS is a runtime error.
As SAPSQL_DATA_LOSS is not a class-based exception, it is not possible to catch it using try catch.
As SAPSQL_DATA_LOSS is not a catchable runtime error, it is not possible to catch it using try catch SYSTEM-EXCEPTIONS.
see the below catchable runtime errors.
https://help.sap.com/doc/abapdocu_751_index_htm/7.51/en-US/abenueb-abfb-sysexc.htm
After some tries I can propose you a possible solution.
This is a workaround:
I don't know if it can be applied to your case, since it needs the select statement to be wrapped into an RFC function module !
The main point is that a short dump (message type X) CAN be handled in RFC calls.
So using an RFC (CALL FUNCTION 'xxxxx' destination 'NONE' for example) and using special exception SYSTEM_FAILURE, the system does not terminate the caller program, but instead it returns a SY-SUBRC > 0 with the Short dump informations in system message fields (SY-MSGxx).
STEPS
Create a Function module (RFC enabled) with your select statement input + the row type of the result table. (All parameters passed by value)
You need this last parameter since generic tables can't be passed in RFC (no "TYPE ANY TABLE" allowed)
FUNCTION Z_DYN_SEL .
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" VALUE(RTAB_NAME) TYPE TABNAME16
*" VALUE(SUB_CONDITION) TYPE STRING
*" VALUE(RESULT_TYPE) TYPE STRING
*"----------------------------------------------------------------------
* RTAB_NAME: DB Table
* SUB_CONDITION: WHERE Condition
* RESULT_TYPE: The ROW type of the internal table
field-symbols <sub_result> type any table.
* DEFINE LOCAL DYNAMIC TABLE TO STORE THE RESULT
data: lr_res type ref to data.
create data lr_res type standard table of (result_type).
assign lr_res->* to <sub_result>.
* DYNAMIC SELECT
select *
from (rtab_name) as rtab
where (sub_condition)
into table #<sub_result>.
* EXPORT RESULT TO A MEMORY ID, SO IT CAN BE RETRIEVED BY CALLER
export res = <sub_result> to memory id 'RES'.
Main program:
In this caller example some parameters are passed to the RFC.
KTOKD field (should be 4 chars long) is passed with a char10 value (producing your short dump).
If ANY Dump is triggered inside the function, we can now handle it.
If everything went fine, IMPORT result from the EXPORT statement inside the RFC
field-symbols <sub_result> type any table.
data: lr_res type ref to data.
create data lr_res type standard table of KNA1.
assign lr_res->* to <sub_result>.
data lv_msg type char255.
call function 'Z_DYN_SEL' destination 'NONE'
exporting
rtab_name = 'KNA1'
sub_condition = `KTOKD = 'D001xxxxxx'`
result_type = 'KNA1'
exceptions
system_failure = 1 message lv_msg.
if sy-subrc = 0.
import res = <sub_result> from memory id 'RES'.
else.
write: / lv_msg.
write : / sy-msgid, sy-msgno, sy-msgty, sy-msgv1, sy-msgv2, sy-msgv3, sy-msgv4.
endif.
RESULTS
After the RFC call in case of a short dump in the select statement, the program is not terminated and the following pieces of information are available
SY-SUBRC = 1
lv_msg is the error text (Data was lost while copying a value.)
Sy-msgid = 00
Sy-msgno = '341'
Sy-msgty = 'X'
Sy-msgv1 = 'SAPSQL_DATA_LOSS'

SSIS 2016 - ErrorColumn is 0 (zero)

I have a package with a bunch of oledb Destinations, using SSIS 2016 - which is supposed to show the exact column that generated the error.The ErrorColumn shows (0) zero, therefore I am unable to trap the column that generated the error.
Using the script below (with code that assigns "Unknown column" but it does not help, it just avoids the script fail):
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
//IDTSComponentMetaData130 componentMetaData = ComponentMetaData as IDTSComponentMetaData130;
//var component130 = this.ComponentMetaData as IDTSComponentMetaData130;
//if (component130 != null)
//{
// System.Windows.Forms.MessageBox.Show(component130.GetIdentificationStringByID(Row.ErrorColumn));
// Row.ErrorColumnName = component130.GetIdentificationStringByID(Row.ErrorColumn);
//}
IDTSComponentMetaData130 componentMetaData = ComponentMetaData as IDTSComponentMetaData130;
if (componentMetaData != null)
{
//
if (Row.wkpErrorColumn != 0)
Row.wkpErrorColumnName = componentMetaData.GetIdentificationStringByID(Row.wkpErrorColumn);
else
Row.wkpErrorColumnName = "Unknown column";
}
else
{
Row.wkpErrorColumnName = "Cannot determine";
}
Row.wkpErrorDescription = ComponentMetaData.GetErrorDescription(Row.wkpErrorCode);
}
In SSIS 2008 (and I believe also SSIS 2016), a zero error column identifies an error that affects the entire row. In the example below, I have created a package that contains only 1 data flow task in the control flow and redirecting all errors and truncations to the error output. Placed a row count task just to have somewhere to send them to.
Also placed data viewers in both error flows to see the data coming out of it.
In a package consuming data from a flat file into an OLE DB Destination:
Using these values as input data
And having name as the PK of the table
We get a PK violation, check the error description and the error column
So when the error affects the entire record, it gets an error column value of 0.
Hope this helps.
I found that
When the error is generated by the PK, the error affect the entire row, and the error column is 0
When the error is generated by a Fk, The error affect only the column, and you get the error column value different then 0

Why SSIS Date Conversion Failure regardles of validation methods

I have a column in a text-file with dates like this: 20131207.
I and trying to convert the date like this but everything I have tried has failed.
Here is my code: I have modified it many times to fix this problem.
(LEN(TRIM(MyDate)) < 8) || (TRIM(MyDate) == " ") ||
(ISNULL(MyDate)) ? NULL(DT_DBDATE) :
(DT_DBDATE)(SUBSTRING(TRIM(MyDate),1,4) + "-" +
SUBSTRING(TRIM(MyDate),5,2) + "-" + SUBSTRING(TRIM(MyDate),7,2))
Where am I going wrong?
I checked Retain Null Values in the Flat Source Task.
Update: Here is the error message:
The conditional operation failed.
The "Rename Columns (My_Table)" failed because error code 0xC0049063 occurred,
and the error row disposition on "Rename Columns (My_Table).Outputs[Derived
Column Output].Columns[MyDate]" specifies failure on error. An error occurred
on the specified object of the specified component. There may be error
messages posted before this with more information about the failure.
I need to convert the data in the text file to date, from 20131207 to 2013-12-07 but I want to insert null if the data in the text file is less then 8 in length or cannot be converted to date.
try this:
add a new flat file source then add a derived column then in expression do this
`LEFT(date,4) + "-" + SUBSTRING(date,5,2) + "-" + RIGHT(date,2)`
the package :
with output like this :
Trim(MyDate)==" " should be Trim(MyDate)==""

Convert String to Datetime (USING SSIS)

I want to insert a value "5/27/2013 16:42:37.490000" (Read from a flat file (DT_STR)) into a column(datetime) of SQL Server table . If I try to cast it with (DT_DBDATE) or DT_DBTIMESTAMP in a derived column , it gives an error .
[Derived Column [130]] Error: SSIS Error Code DTS_E_INDUCEDTRANSFORMFAILUREONERROR. The "component "Derived Column" (130)" failed because error code 0xC0049064 occurred, and the error row disposition on "output column "Derived Column 1" (155)" specifies failure on error. An error occurred on the specified object of the specified component. There may be error messages posted before this with more information about the failure.
How can I go about it ?
Thanks
The value is a datetime2 type .AFAIK SSIS doesn't support datetime2 .You need to store it in database as string and then update the column by converting it to datetime2.
Here is Microsoft Connect Issue
Update: Using DT_DBTIMESTAMP2 you can convert the string to proper datetime format
The below code works perfectly fine in Derived Column
(DT_DBTIMESTAMP2,7)"2013-5-27 16:42:37.490000"
7 is the precession here .The above code won't work if the format of datetime is different.For example MM/DD/YYYY HH:mm:ss.ffffff .
However you can use Script component and pass array of different datetime formats to Datetime.ParseExact function
Step1: Drag a Script component and create a new output column of DT_DBTIMESTAMP datatype and name it as NewDate.
Step2: Write the below C# code
public override void Input0_ProcessInputRow(Input0Buffer Row)
{
string[] format = new string[] { #"M/dd/yyyy HH:mm:ss.ffffff",
#"MM/dd/yyyy HH:mm:ss",
#"M/d/yyyy HH:mm:ss" ,
#"M/dd/yyyy HH:mm:ss.ffffff",
#"MM/dd/yyyy HH:mm:ss.ffffff",
#"M/d/yyyy HH:mm:ss.ffffff"};
DateTime dt = DateTime.ParseExact(Row.Date,
format ,
CultureInfo.InvariantCulture,
DateTimeStyles.None);
Row.newDate = dt;
}
I won't say it's the perfect solution, but just a workaround.
Format the input and then insert. The formatted data after using the below expression works well with either datetime or datetime2.
SUBSTRING(TMS_CREAT,(FINDSTRING(TMS_CREAT,"/",2) + 1),4) + "-" + SUBSTRING(TMS_CREAT,1,(FINDSTRING(TMS_CREAT,"/",1) - 1)) + "-" + SUBSTRING(TMS_CREAT,(FINDSTRING(TMS_CREAT,"/",1) + 1),2) + SUBSTRING(TMS_CREAT,(FINDSTRING(TMS_CREAT,"/",2) + 5),16)