Execute SQL Task -Full Result Set Datatype Mismatch Error - sql

I am creating an SSIS package which has an execute SQL task and it passes result set variable to a for each loop container.
My Sql Query is:
Select distinct code from house where active=1 and campus='W'
I want the execute sql task to run this query and assign its results to a variable which is passed to a for each loop container which should loop through all the values in the result set.
But my execute sql task fails with error:
The type of the value (DBNull) being assigned to variable
"User::house" differs from the current variable type (String)
Now i have done my research and i have tried assigning the variable datatype Object but did not work. I tried using cast in my sql query and that also did not work.
Since my query returns multiple rows and one column, i am not sure how i can assign a datatype to the whole query?
Sample:
Code
AR
BN
CN

It sounds like you have a variety of issues in here.
Result Set
The first is in your Execute SQL Task and the need for agreement between the Result Set specification and the data type of the Variable(s) specified in the Result Set tab. If you specify Full Resultset, then the receiving object must be of type System::Object and you will only have 1 result set. The type of Connection Manager (ODBC/OLE/ADO) used will determine how you specify it but it's infinitely searchable on these fine forums.
The other two options are Single Row and XML. In 13 years of working with SSIS, I've never had cause to specify XML. That leaves us with Single Row. For a Single Row Result Set, you need to provide a variable for each column returned and it needs to be correctly typed.
To correct your issue, you need to declare a second variable. I usually call my rsObject (record set object) and then specify the data type as System.Object.
For Each Loop Container
Your For Each Loop Container will then be set with an Enumerator of "Foreach ADO Enumerator" and then the ADO object source variable will become "User::rsObject"
In the Variable Mappings, you'll specify your variable User::house to index 0.
Testing
Given a sample set of source source data, you can verify that you have your Execute SQL Task correctly assigning a result set to our object and the Foreach Loop Container is properly populating our variable.
SELECT DISTINCT
code
FROM
(
VALUES
('ABC', 1, 'w')
, ('BCD', 1, 'w')
, ('CDE', 0, 'w')
, ('DEF', 1, 'w')
, ('EFG', 1, 'x')
) house(code, active, campus)
WHERE
active = 1
AND campus = 'w';
If you change the value of campus from w to something that doesn't exist, like f then things will continue to work.
However, the error you're receiving can only be generated if the code is a NULL
Add one more entry to the VALUES collection like
, (NULL, 1, 'w')
and when the For Each Loop Container hits that value, you will encounter the error you indicate
The type of the value (DBNull) being assigned to variable "User::house" differs from the current variable type (String)
Now what?
SSIS variables cannot change their data type, unless they're of type Object (but that's not the solution here). The "problem" is that you cannot store a NULL value in an SSIS variable (unless it's of type object). Therefore you need to either exclude the rows that return a NULL (AND code IS NOT NULL) or you need to cast the NULL into sentinel/placeholder value as a substitute (SELECT DISTINCT ISNULL(code, '') AS code). If an empty string is a valid value, then you need to find something that isn't - "billinkcisthegreatestever10123432" is unlikely to exist in your set of codes but that might be a bit excessive.
Finally, think about renaming your SSIS variable from house to code. You might be able to keep things straight but some day you'll hand this code over to someone else for maintenance and you don't want to confuse them.
A picturesque answer https://stackoverflow.com/a/13976990/181965

the variable "User::house" is string , so , did you use it in result set?

you need declare son "object" var for result set
result set
then declare a string variable for every single Code from your result
For Each Loop Container
good luck

Related

SSIS: How do I pass string parameter in an update statement in Execute SQL Task?

I have one execute SQL Task in SSIS 2012 which has update statement. I want to pass a string variable in the where clause of this update statement. The update section is as below:
where coalesce(s1.iteration, '') not like '%?%' and s2.Iteration = '?'
Here, ? needs to be replaced with a string variable, which in this case would be 08152017. I have added the variable to the Parameter Mapping. Screenshot is attached.
The task executes successfully but does not updates the value in the intended column. It seems the query is not passing the value.What am I doing wrong? How do I check that the SQL inside the Execute SQL Task is actually getting the value from the variable?
First of all, when you set your variable in parameter mapping, make sure the datatype is NVARCHAR and not LONG.
Second you need to write your statement like this:
where coalesce(s1.iteration, '') not like '%?%' and s2.Iteration = ?
You dont need '' because your variable is already set as a string.
Try to hardcode your value in your variable to see if it passes. Otherwise, set a breakpoint on pre-execute to see wheter your variable has a value.
If your variable has a value and your SQL is not working, maybe you should look into your SQL. Maybe try it directly in SSMS to see if it actually runs or does anything.
In scenario ? is Integer type variable, then please use below format:
SELECT ? +' Hello World!'
The above does not require the use of an additional string variable.
Create a user variable with % on it, for example, variable name is Like_Var with data type String
"%" + #Orig_Var + "%"
Let's say, Orig_Var has a value of 08152017, therefore Like_Var will have %08152017%
Then use Like_Var on your parameter in Execute SQL Task as parameter 0, data type VARCHAR in Parameter Mapping
WHERE COALESCE(s1.iteration, '') NOT LIKE ?
AND s2.Iteration = ?

Compare parameter in WHERE clause stored procedure

I have a stored procedures which receives a list of ItemId's. If the list only contain one item this works:
AND (#OrgItemIds = -1 OR ...)
AND (#OrgItemIds = -1 AND...)
but if the list contains more than one item it crashes.
Anybody knows how to fix this? Can I check the size of the list somehow?
Or can I check just the first element of the list like #OrgItemIds[0] or something like that?
There is no "comma-separated set of values" or "array" datatypes in SQL SERVER. You handle the parameter as a scalar variable in your code. Thus when you provide a single value in that list, server implicitly converts it to int and your sp succeeds.When you provide string with commas - it becomes impossible to convert it to int.You have to manually parse your argument, put it into a table variable and then use this table in WHERE clause. Or change handling of this argument to support a string of values instead of scalar value:
... where #OrgItemIds like '%,' + cast(t.OrgItemIds as varchar(10)) + ',%'
which is much worse for performance than filtering by id or list of ids.

SSIS to handle SQL binary data type

I am strugling wiith handling a sql binary(8) data type.
No matter what I try to do with it inside the SSIS package, it always fails with an error of: "Invalid cast specification"
Let me describe what I am tying to do in details:
I have a single row that I am assigning to a variable in a SQL Task in the control flow.
select max(LastRowVersion as bigint) as MinRV from MyTable
LastRowVersion is of datatype binary(8).
2.Then I am assigning the result to variable - User::MaxRowVersion
If I configure MaxRowVersion to be of String or Object data type, then this part works fine.
3.Next I am opening a data flow task with the following select statement:
select fields
from AnotherTable
where LastRowVersion > ?
and assigning User::MaxRowVersion to the query.
Again LastRowVersion is of datatype binary(8) in the table - AnotherTable.
Here is where I am getting the error that I mentioned above.
I have tried various types of playing with the DT_BYTES cast type in the expression of the User::MaxRowVersion variable, but it is failing.
I have also read that there is a possibility to open a C# script task to handle it or that Dynamic SQL can help, but I would rather keep the solution as simple as possible with no scripting if possible.
Thanks for the help,
Dani
Have you tried this?
Keep MaxRowVersion as a Sting data type
Cast the variable reference in the SQL statement
Example:
"
SELECT my_field
FROM my_table
WHERE LastRowVersion > CAST('" + #[User::MaxRowVersion] + "' as MyDataType);
"

Convert String Variable to Datetime Returns Incorrect Value in SSIS

Following my question in https://stackoverflow.com/questions/7387418/where-clause-using-date-taken-from-string-variable-sent-out-incorrect-return-in-s, this is the simplified version of the question:
The query used for the OLE DB Source is this, with a string type variable inside:
select
*
from
A
where
A.A_IN_DATETIME < CONVERT(DATETIME,?,105) and
(A.A_OUT_DATETIME is NULL or A.A_OUT_DATETIME >= CONVERT(DATETIME,?,105))
The query above works inside a Foreach Variable Enumerator, with the variable used is an array of string variable consisting of this: 13-09-2011,12-09-2011,11-09-2011,10-09-2011,09-09-2011,08-09-2011,07-09-2011,06-09-2011,05-09-2011,04-09-2011,03-09-2011,02-09-2011,01-09-2011
The condition for the problem is this: For example, there is a record in A with A_IN_DATETIME = 2011-09-12 (YYYY-MM-DD format) and A_OUT_DATETIME = NULL.
The correct result for the query above that it should have been only returning values for 13-09-2011 and the rest return 0 records, but in the execution, there was a result for 12-09-2011 to 10-09-2011 also. I don't know if the SSIS somehow mistaken the 12-09-2011, 11-09-2011, 10-09-2011 to 09-12-2011,09-11-2011,09-10-2011 (FYI, I've checked the parsing result and also the loop enumerator by printing it out in a message box generated from the script task, and it is still in its correct form).
Is there any solution for this problem?
Run Sql Profiler and see what query comes through to SQL Server. This will allow you to re-run the exact query in SSMS and see the results right there.
I don't believe conversion to DATETIME accepts a format, i.e. 105.Try this instead:
CONVERT(DATETIME, '9/13/2011 15:37:00')
Result is DATETIME - 2011-09-13 15:37:00.000

How do I assign numeric value of an SQL query result to a package variable of data type Double?

I have what should be a simple task - Populate a user variable using the ResultSet from an Execute SQL task
SELECT MainID FROM TableA WHERE TableA_ID = 1`
(This will only return one Column and one Row).
MainID is currently stored as a user-defined datatype in the database. The value is stored in the format XXXX.Y (e.g. 8008.1).
If I change the UserVariable to a String datatype, I can assign the value without any problems either CASTing or CONVERTing the ResultSet to STRING/NUMERIC/FLOAT.
SELECT CAST(MainID as NUMERIC(9,1)) as 'MainID' FROM TableA WHERE TableA_ID = 1;
SELECT CAST(MainID as FLOAT) as 'MainID' FROM TableA WHERE TableA_ID = 1;
SELECT CAST(MainID as VARCHAR(10)) as 'MainID' FROM TableA WHERE TableA_ID = 1;
or
SELECT CONVERT(NUMERIC(9,1), MainID) as 'MainID' FROM TableA WHERE TableA_ID = 1;
SELECT CONVERT(FLOAT, MainID) as 'MainID' FROM TableA WHERE TableA_ID = 1;
SELECT CONVERT(VARCHAR(10), MainID) as 'MainID' FROM TableA WHERE TableA_ID = 1;
However, I can't assign the value if the User Variable Datatype is DOUBLE. I get the following error message:
[Execute SQL Task] Error: An error occurred while assigning a value to
variable "dUserVariable": "The type of the value being assigned to
variable "User::dUserVariable" differs from the current variable type.
Variables may not change type during execution. Variable types are
strict, except for variables of type Object. ".
I'm fairly new to SSIS so I'm a bit stumped on how to get this conversion to go through.
Any ideas?
I am not sure if the following option will work in Web Service Task but you can give it a try.
I think that the issue you have described is due to a limitation in SSIS while assigning numeric value to an SSIS package variable of data type Double. Refer this link to MSDN Connect where this issue has been reported.
Here is a simple step-by-step example that illustrates an option that you can try. This example was created in SSIS 2008 R2.
Create an SSIS package. I have named the package in the format YYYYMMDD_hhmm in the beginning followed by SO stands for Stack Overflow, followed by the SO question id, and finally a description. This is for me to easily refer this back later. Refer screenshot #1.
On the package, create two variables namely StringValue and DoubleValue. Set the variable StringValue to numeric value (say 0). This is necessary so that the expression we are going to configure in the variable DoubleValue doesn't error out. Select the variable DouleValue and press F4 to view the properties. Set the property EvaluateAsExpression to True and set the Expression property to (DT_DECIMAL, 2) #[User::StringValue] NOTE: At this point the Data Type on the variable DoubleValue will change to Cell is not a string. Refer screenshots #2 and #3.
On the package, create an OLE DB connection manager to some SQL Server database. I have created a connection to Adventure Works database that I have on my local machine. Refer screenshot #4.
On the Control Flow tab, place an Execute SQL Task and configure it as shown in screenshots #5 and #6. Double-click on the Execute SQL Task to bring the Execute SQL Task Editor. Set the ResultSet to SingleRow because we will be fetching only one value. Set the connection string to the OLE DB connection manager. The SQL Statement should be set to SELECT CAST('3.14' AS NUMERIC(10,2)) AS ValueOfPi. Result Set should be set to the variable StringValue.
On the Control Flow tab, place a Script Task after the Execute SQL Task. This script task is just to show the value that will be assigned to the DoubleValue variable due to the expression that we just configured. Double-click on the Script Task to bring the Script Task Editor. Click on the Edit Script... button to bring the VSTA editor. Replace the Main() method with code given under Script task code section. Refer screenshots #7 and #8.
Execute the package. The value in the variable DoubleValue should be displayed in a message box. Refer screenshot #9.
Hope that helps.
Script task code:
C# code that can be used only in SSIS 2008 and above.
public void Main()
{
Variables varCollection = null;
Dts.VariableDispenser.LockForWrite("User::DoubleValue");
Dts.VariableDispenser.GetVariables(ref varCollection);
MessageBox.Show(varCollection["User::DoubleValue"].Value.ToString());
Dts.TaskResult = (int)ScriptResults.Success;
}
Screenshots:
#1:
#2:
#3:
#4:
#5:
#6:
#7:
#8:
#9: