I have a simple job that grabs Employee IDs and sends them to an API call, which only accepts one Employee ID at a time. I have this setup using a ForEach Loop Container being fed by an Execute SQL Task.
The job runs as expected, but it is only looping through the top N record.
My Execute SQL Task is returning a full result set to a variable. My variable is set as an Object data type.
I have the ForEach Loop set to Foreach ADO Enumerator, then matched to my variable.
When I run the job I don't get a specific error message telling me what I'm doing wrong, but it fails at the ForEach Loop as shown
Anything else I can look out for?
The Execute SQL Task needs to shove results into an SSIS variable of Object type. I assume associateOID is a string type, yeah?
What you need to do is create an SSIS variable called something like rsEmployees of type Object. Your ResultSet in Execute SQL Task will then map to User::rsEmployees
Change the Foreach Loop ADO enumerator to use the variable User::rsEmployees
At this point, the package will execute and store the results into our rsEmployees variable and then the Foreach enumerator will iterate through the records in our set. The last piece is to do something with the current row. That's where your User::associateOID comes into play.
In the Variable Mappings tab of the Foreach Enumerator, add User::associateOID to ordinal 0. That will provide the linkage between the "current row" that is being shredded in the enumerator and our SSIS variables
Related
I need to use a result from SQL SELECT which should return an array of IDs to iterate through it in my foreach loop.
I'm quite new to SSIS. I created Execute SQL Task, connect to DB and write
SELECT ID FROM TABLE
Then I created Script Task and connect these two components with Constraint. But I don't know how to pass result from SQL Task into an object in Script Task.
The typical pattern you are looking for is this:
1. In execute SQL you need to:
a. Assign the connection
b. Add your SQL Statement
c. Change Result Set to Full Result Set
d. Map the result set to an Object type variable
2. In Foreach
a. Change enumerator to ADO Enum
b. Assign your variable from #1
c. Map a variable to the interation
****EDIT****
3. Change out data flow for script task
a. Pass in iteration variable
b. in script create the URL as a string
c. use webclient to connect to web service
string url = #"https://www.blah.com? ID=" +
Dts.Variable["variable"].Value.ToString();
WebClient wc = new WebClient();
string result = wc.DownloadString(url);
4. Now you have to do something with that result
I am running that uses multiple Foreach Loop Containers and want to run them simultaneously. However, I get the error message -
COM error object information is available. Source:
"ADODB.Recordset" error code: 0x800A0BCD Description: "Either BOF or
EOF is True, or the current record has been deleted. Requested
operation requires a current record."
Obviously, once one Foreach Loop process completes the result set gets dropped.
To get around this I assumed you can pass the same data to different variables like so -
Then in each of the loops just change the DBList, with one Foreach Loop being DBList and the other DBList2 -
However, I receive the error message -
There is an invalid number of result bindings returned for the
ResultSetType: "ResultSetType_Rowset".
Is it impossible to run multiple Foreach Loops concurrently?
You can run foreach loops concurrently, but you have to get your resultset into multiple object type variables and you also have to have 2 sets of variables you would use for the variable mappings for each of the foreach loops.
Example:
Your data flow will consist of a source, multicast and 2 different RecordSet destinations:
The example source here is just returning 1 column of a list of numbers. We multiple cast that into 2 separate RecordSet Destinations that are then assigned to their own object variable type. In this example I have 2 variables, User::RecordSet1 and User:RecordSet2.
Then each of the foreach loops is configured to each of those variables:
Then you have separate variables for each of the foreach loops:
From there you'll need to make sure you're using the appropriate set of variables in whatever code you have in each of the foreach loops.
Instead of using an Execute SQL Task, create a Data Flow, and then use a SQL Query as your Source (probably OLE DB Source). Then pipe that to a Multicast, with outputs to two different Recordset Destinations. In the Component Properties tab, set the VariableName to one of your object variables, then click on the Input Columns to choose which columns you want to include. Do the same for the other Recordset Destination, choosing your second object variable this time, and again selecting which columns to include. Then go back to your Control Flow and link the Data Flow you just created to your two Foreach Loop Container.
I am getting below error while running my ssis package.
Error: COM error object information is available. Source: "ADODB.Recordset" error code: 0x800A0BCD Description: "Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.".
I am storing a value in an object variable using RecordSetDestination. And I am passing the object variable in 3 ForEachLoop containers and I am trying to run it parallel. If one of the container is passed then the rest of them getting failed.
Below is the same configuraiton in all 3 ForEachLoop's
Any property needs to change or object variable need to rest or we can't use the object variable for parallel exec in ForEach ADO Enumerator.
Need your input here... Thanks
The problem is the variable for the recordset.
The first option would be you add three data flows like origins pointing each one to a different variable.
The second is adding a multicast in your initial data flow, with three outputs, each one pointing to a different variable.
Then you go to each Foreach Loop Container and set the respective variable in the Enumerator configurarion section.
As Ferdipux proposed, try to run Foreach Loops sequentially. This worked for me.
I have a scenario where i need to pass an text file or excel file column as an parameter to my Sql Query in SSIS Package.
My Text or excel file has a column called Policy_no and it has more than 1000+ policy_no(EX: 12358685). i have an Sql script *select * from main_table where policy_no = ?*. And that that '?' has to be come from my package variable(txt or excel ).
Instead of manually writing script for each and every policy, how can we achieve this through SSIS.
Thanks
Assuming you want to loop through each row in your file and run the query against each individual value, you can use a Data Flow task to read your text file and load the policy numbers in an ADO Recordset (declared as a package variable). Next, you'd use a Foreach Loop Container to iterate through the recordset, loading each policy number in turn into a second variable and then executing your query and doing whatever other work is needed.
See Use a Recordset Destination in MSDN for an overview and example.
You can use EXECUTE SQL TASK (Connect Excel with OLE DB Connection) to get "Policy_no" data from Excel, then store the result into a variable, say:policyNoGroup, whose data type should be Object, then use For Each Loop to loop though variable policyNoGroup, see the example: http://www.codeproject.com/Articles/14341/Using-the-Foreach-ADO-Enumerator-in-SSIS
I've two nested foreach loop containers. Each are looping on different resultsets. I've a script task, within the inner foreach loop container, in which I need to be able to acccess values of current row of both the loops. One way of doing it is using variable mappings on both the loops, but is there a way to access current row from within the script? any ideas?
You can access variables mapped in loop containers in script task via Variables property of the Dts object if you add this variables to ReadOnlyVariables or ReadWriteVariables lists in the Script Task Editor.
Map current row of each loop to variable and then access this variables in script task. Isn't this enough?
Example:
string fileName = (string) Dts.Variables["FileName"].Value;
You can read more here: http://msdn.microsoft.com/en-us/library/ms135941.aspx
Update:
You can map whole row to variable at once. Use Object as variable type and set Index = -1 in Variable mappings in Foreach loop.You should receive enumerator, which type is related to enumerated collection.