One of the looping constructs available in SSIS packages is the Foreach Loop Container. One of its enumerator options is the For Each Item Enumerator. It enumerates through a list of items populated at design time. The list is static at execution time, i.e. the list items can not be dynamically loaded from a configuration file or a another source like an SQL table. Probably due to the static nature of the item list, this enumerator type is not used too often in packages.
On the other hand, there are some scenarios where a static list can prove to be useful. For example -
- no need to create a database table just to pass on values for the Foreach Loop
- enforce a specific order to the parameters passed to the loop
- initialize variables values with the Item Enumerator instead of doing that in a Script task
An another frequent requirement in SSIS packages is to execute a set of operations against different SQL Servers or databases. The package should change the OLE DB connection string dynamically during execution to point towards the appropriate target. A looping construct iterates through the list of servers and databases, and the package Expressions change the OLE DB connection properties.
I am creating this step-by-step scenario to demonstrate the use of a Foreach Item Enumerator and use it to make a dynamic OLEDB connection. A single query is executed in a loop against three different SQL databases and the output is exported to a single text file.
The steps -
Add a Foreach Loop Container to your SSIS package. Double-click on it to open its editor. Click on the Collections tab on the left of the editor. Select the enumerator as Foreach Item Enumerator. Click on the Columns… button. Add two columns of String type. As you add columns, the editor gives them names like Column0, Column1 and so on, and there is no way to customize these names.
Populate the column values by simply typing in the rows. Use Column0 for server names and Column1 for corresponding database names on that server. I have used my local server for all three rows but you can use your own server names here. This is the list of items that are iterated by the Foreach Loop.
Now you need two variables that will hold the values shredded from the item list as the Foreach Loop iterates through the rows. These variables are used later in the Property Expressions of the OLEDB connection to make it dynamic.
Click on Variable Mappings tab on the left and then on the <New Variable…>
Add two variables of String type, namely ServerName and DatabaseName.
The Index 0 and 1 of the variables correspond to the Column0 and Column1 of the Foreach Item list respectively.
That is all there is to it. Now the loop is ready to iterate through the item rows.
Let us move on to the dynamic OLEDB connection. Add a Data Flow Task to the Foreach Loop Container.
Double-click the Data Flow Task to view its design surface. Now add one OLE DB Source.
Double-click OLE DB Source to set its properties. First window is of its connection manager.
Once the connection information is done, you will view its properties editor. Set the Data Access Mode to SQL Command and put the following query in the SQL Command Text -
@@SERVERNAME as ServerName
,DB_NAME() as DatabaseName
,GETDATE() as LogDateTime
,COUNT(*) as NumberOfIndexes
Clicking the Columns tab is important so that the SSIS can find the metadata like column names, data types etc. from the underlying tables/views. If you don’t do this then you’ll find later that SSIS does not know of this metadata.
Again, it is a good idea to drag the connector from OLEDB source to the Flat File destination before modifying the Flat File destination properties. In this way, the SSIS Designer helps you by matching the destination with the source metadata automatically. Otherwise you have to perform some extra steps to match columns. I hope you like to save time as much as I do!
Give a file path and check the box for Column Names in the First Row.
Verify the column mappings in the Mappings tab.
The trick to make the OLEDB connection string dynamic lies in the next couple of steps where you edit the properties of the OLEDB connection and assign expressions to its ServerName and InitialCatalog properties.
The property ServerName gets the variable @[User::ServerName] and the property InitialCatalog gets the variable @[User::DatabaseName]. Remember that these variables will get their values modified during each iteration of the Foreach Loop and as a result the OLEDB connection string will get modified too.
The last step is just to make sure that data is appended to the destination text file instead of being overwritten with each loop iteration and new source connection.