SSIS: Convert between Unicode and Non-Unicode Strings - sql-server

Setup
I have a data flow task with:
An OLE DB Source selecting all data from a database table (SQL Native)
An OLE DB Destination of an Access 2003 File template (MS Jet 4.0)
So Essentially I am selecting a table and inserting it into a .mdb file.
Problem
I have the error:
column [X] cannot convert between unicode and non-unicode string data types
However If I add a 'Data Conversion Step' to convert all columns of type DT_STR to DT_WSTR, that error message goes away however I get the error message:
[DTS.Pipeline] Error: "component "OLE DB Source" (6289)" failed validation and returned validation status "VS_NEEDSNEWMETADATA".
Iv'e been Googling this problem for a while and still can't fix it.
Any ideas?

Instead of
Select * from tblName
use
Select col1, col2, col3, etc from tblName
The reason I found is, when you use different database, they might have one or two column that cause issue as it's not mapped. So when you use table query, be specific regarding column name.

Related

Bulk Insert Task Error in ssis

While running ssis Bulk insert i got the following error.
An error occurred with the following error message: "Cannot fetch a row from OLE DB provider "BULK" for linked server "(null)".The OLE DB provider "BULK" for linked server "(null)" reported an error. The provider did not give any information about the error.The bulk load failed. The column is too long in the data file for row 1, column 1. Verify that the field terminator and row terminator are specified correctly.".
To solve the problem i have change the connection timeout to 0 and to 5 . That did not work .
I also reviewed the data on row 1 column 1.
"In order to avoid these kinds of issues, I always import all fields as varchar fields into a staging table, then convert them into the data type required. You will have much more control."
You can get more details from the following link:
https://social.msdn.microsoft.com/Forums/sqlserver/en-US/5caa8c0a-2328-4c9e-9894-eaba12e8196a/data-conversion-error-during-bulk-insert?forum=sqlgetstarted

Data flow task fails at source because of datetime conversion? SSIS 2008

Ive seen this type of error before (eg truncation) with strings before but not with datetime fields.
Have a Data flow task that seems to fail at the source. The OLEDB data source is a call to a procedure and among the columns of the resultset is a datetime field GAPPOSTDT. The return value is a datetime and the procedure returns just fine with the expected results. Not so when I run this through the data flow task. Looking at the advanced properties of the oledb source, I see the type for this field set to database timestamp [DT_DBTIMESTAMP] which seems right.
What could be causing this field not to get mapped?
Ive tried simply deleting the dataflow task and recreating it. Same issue.
See error message below.
Error: 0xC020901C at Data Flow Task, OLE DB Source [1]: There was an
error with output column "GAPOSTDT" (61) on output "OLE DB Source
Output" (11). The column status returned was: "The value could not be
converted because of a potential loss of data.". Error: 0xC0209029 at
Data Flow Task, OLE DB Source [1]: SSIS Error Code
DTS_E_INDUCEDTRANSFORMFAILUREONERROR. The "output column "GAPOSTDT"
(61)" failed because error code 0xC0209072 occurred, and the error row
disposition on "output column "GAPOSTDT" (61)" 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.
[UPDATE #1]
SSIS 2008
So I changed the procedure output to return varchar(10) instead of datetime. The OLEDB Source in the dataflow now errors with the following
Error: 0xC020901C at Data Flow Task, OLE DB Source [1]: There was an error with output column "GAPOSTDT" (61) on output "OLE DB Source Output" (11). The column status returned was: "Text was truncated or one or more characters had no match in the target code page.".
Error: 0xC020902A at Data Flow Task, OLE DB Source [1]: The "output column "GAPOSTDT" (61)" failed because truncation occurred, and the truncation row disposition on "output column "GAPOSTDT" (61)" specifies failure on truncation. A truncation error occurred on the specified object of the specified component.
Im now suspecting some "goofy" characters in the data. The collation being used in the source system is SQL_Latin1_General_CP1_CI_AS
[UPDATE #2]
Ok, I think I may have found the issue. In my procedure I have a "dummy" result because my procedure uses temp tables and this is one "work around" with SSIS (see other topics on this). My final result and the dummy result had their columns in the wrong order. So this put data into the wrong columns. I noticed this when I put on a data viewer. After it popped up, I noticed data into the wrong columns. Strange I thought, then after reviewing my procedure, I found the culprit.
There are always problems with datetime fields... ;)
Try to convert this field to string in the query on the source and then apply changes needed with Derived Column Transformation. Where I live we use date format dd.mm.yyyy, but I'm getting at least 3 other different formats of date...
Maybe this is not the best answer but it's worth to try... it suits me well... :)
That is because the data type of input column does not match the destination column well. You mentioned that you have seen that before fot the varchar column, that is because the size(data length) of input record for that column is smaller than the destination, if input is varchar(30), destination is varchar(20), that will cause this issue. Check your datatype, I am guessing there may have some conflicts when you are trying to do with datetime and datetime2, or datetimeoffset
for example:
input varchar(30) destination varchar(30) perfectly match
input varchar(20) destination varchar(30) fine but a warning
input varchar(30) destination varchar(20) if actual is smaller than 20, that is fine, but if bigger than 20, cause error

How to add null value if a column doesn't exist

I have a package in my ETL that loops through 4 different databases, each with a copy of the same table. I found out that one of the four tables has one extra column named MTFvalue_Permit thus giving me the below error. My fact and staging tables, however, do include this column.
I was hoping ssis would just insert a null value if the column didn't exist. How can I add a null value into my Data Warehouse tables for the other three tables in which this column doesn't exist?
Error:
[Source DB IBS [1]] Error: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80040E14.
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 10.0" Hresult: 0x80040E14 Description: "Statement(s) could not be prepared.".
An OLE DB record is available. Source: "Microsoft SQL Server Native Client 10.0" Hresult: 0x80040E14 Description: "Invalid column name 'MTFvalue_Permit'.".
Edit: I'm thinking about using a case statement like this for the query but I'm getting a different error.
SELECT
[blahblahblah] ,
[blahblahblah] ,
[blahblahblah] ,
[blahblahblah] ,
[blahblahblah] ,
CASE WHEN COL_LENGTH('wmManifests', 'MTFvalue_Permit') IS NOT NULL
THEN [MTFvalue_Permit]
ELSE NULL
END AS 'MTFvalue_Permit'
FROM dbo.wmManifests
Invalid column name 'MTFvalue_Permit'.
I don't think that you can do it using expressions.
You can do this workaround.
Add a Script task that list columns from the table
Build the Select query dynamically:
If the column is not found pass NULL instead of the column name and give an alias (same as column name)
save this query string into a SSIS variable and use it as a source
You can also create a stored procedure that generate the query string. Execute it from a sql task and store the query string into ssis variable
Perhaps I am not understanding your question, but it seams like you are approaching this problem backwards. You cannot insert data into columns that do not exist. Is there a reason this column exists in only one out of four versions of this table? And does this column have a default value that you can leverage?
I would continue inserting to the set of columns that are common among all tables and allow the tables with columns that do not exist in every one of the tables in the set to use the default value for that column.

The binding status was "DT_NTEXT". The data flow column type is "DBBINDSTATUS_UNSUPPORTEDCONVERSION"

I have the following query in Access:
SELECT Field1, Field2, Field3, "2015" As TestYear
FROM Table1
I use this query in SQL Server Import/Export tool to get data from Access database into SQL Server database.
I keep getting an error:
"(SQL Server Import and Export Wizard)
Error 0xc002f446: Data Flow Task 1: An error occurred while setting up a binding
for the "TestYear" column. The binding status was "DT_NTEXT". The data flow column type is "DBBINDSTATUS_UNSUPPORTEDCONVERSION".
The conversion from the OLE DB type of "DBTYPE_IUNKNOWN" to the destination column type of "DBTYPE_WVARCHAR" might not be supported by
this provider.
The destination table column for TestYear is of type nvarchar.
I checked the source in my import package and the column is shown as LongText. I am not sure why since the column's length is only 4.
Can anyone please help me fix the problem?
If I recall correctly, in the same tab where you can see that the "2015" column has a LongText datatype you can actually convert it to DT_WSTR which is a unicode widestring which should fit into a NVARCHAR column. If you aren't able to convert it in the tool, adding CVar("2015") AS TestYear should also convert it in the MS Access query and allow it to be imported to SQL Server.
If this doesn't work I think we'll need more information on what kind of tool or wizard you were using at the time of this post to provide help.

SSIS OLEDB Command transformation (Insert if not exists)

Ok so according to Microsoft docs the OLE DB Command Transformation in SSIS does this
The OLE DB Command transformation runs an SQL statement for each row in a data flow. For example, you can run an SQL statement that inserts, updates, or deletes rows in a database table.
So I want to write some SQL to Insert rows in one of my tables only IF the record doesn't exists
So I tried this but the controls keeps complaining of bad sintaxys
IF NOT EXISTS
(SELECT * FROM M_Employee_Login WHERE
Column1=?
AND Column2=?
AND Column3=?)
INSERT INTO [M_Employee_Login]
([Column1]
,[Column2]
,[Column3])
VALUES
(?,?,?)
However if I remove the IF NOT EXISTS section (leaving the insert only) the controls says may code is Ok, what am I doing wrong.
Is there an easier solution?
Update: BTW My source is a Flat File (csv file)
Update since answer: Just to let people know. I ended up using the OLE DB Command Transformation like I planned cause is better than the OLE DB Destination for this operation. The difference is that I did used the Lookup Component to filter all the already existent records (like the answer suggested). Then use the OLE DB Command Transformation with the Insert SQL that I had in the question and it worked as expected. Hope it helps
OLEDB Command object is not the same as the OLE DB Destination
Rather than doing it as you describe, instead use a Lookup Component. Your data flow becomes Flat File Source -> Lookup Component -> OLE DB Destination
In your lookup, you will write the query SELECT Column1, Column2, Column3 FROM M_Employee_Login and configure it such that it will redirect no match entities to the stream instead of failure (depending on your version 2005 vs not 2005) this will be the default.
After the lookup, the output of No Match will contain the values that didn't find a corresponding match in the target table.
Finally, configure your OLEDB Destination to perform the fast load option.
Though you can make use of Look up component in SSIS to avoid the duplicates which is the best possible approach, but if you are looking for some query to avoid the duplicates then, you can simply insert all the data in some temp/staging table in your database, and run the following query.
INSERT INTO M_Employee_Login(Column1, Column2, Column3)
SELECT vAL1,vAL2,vAL3 from Staging_Table
EXCEPT
SELECT Column1, Column2, Column3 FROM M_Employee_Login

Resources