Dynamically Add Tables in SSIS Source Queries

I recently encountered a situation where I was using a source SQL Command inside an OLE DB Source in SSIS DFT and a simple query using three tables. The query was relatively simple – just calling the common columns from the tables using ‘UNION ALL’.  The package was set and in the production environment. 

Subsequently, there was an enhancement in the module and one new extra table was added with the same common columns. I needed to refer this new table in the same way as the three previous tables, using the common columns with ‘UNION ALL’.  Due to this, I needed to go and change the Package source query in the sql command again.

This procedure worked perfectly well but for additional enhancements I wanted a more generalized solution. After much deliberation and testing I finally ended up with a solution using variables.

Solution Walkthrough

I have three tables, having three common columns RowID and VersionNo.

1) Demo1 ( RowID , VersionNo)

2) Demo2 ( RowID , VersionNo)

3) Demo3 ( RowID , VersionNo)

The below script will create these tables :

CREATE TABLE demo1 (RowID INT, Versionno INT, demo1comments VARCHAR(50))
CREATE TABLE demo2 (RowID INT, Versionno INT, demo2comments VARCHAR(50))
CREATE TABLE demo3 (RowID INT, Versionno INT, demo3comments VARCHAR(50))

As shown in the script, all the three tables have two common columns(RowId and Versionno)  and one column for the table. I have to get all the common columns Rowid and VersionNo from these table and insert into the destination table.

Now, we can insert some data into these tables :

INSERT INTO demo1
SELECT 1,1,'demo1' UNION ALL
SELECT 1,3,'demo1' UNION ALL
SELECT 1,8,'demo1'
INSERT INTO demo2
SELECT 1,2,'demo2' UNION ALL
SELECT 1,5,'demo2' UNION ALL
SELECT 1,9,'demo2'
INSERT INTO demo3
SELECT 1,4,'demo3' UNION ALL
SELECT 1,6,'demo3' UNION ALL
SELECT 1,7,'demo3'

The aim behind the column RowId and VersionNo, is THAT RowID representS a complete row or a batch which is further divided into pieces with VersionNo. I want to combine and consolidate everything into a single table using SSIS which can represent a complete row with all the versions.

As per the demo data inserted, the three tables have one RowID and 9 versions split across all the tables.

Now, begins the main solution. My first step was to create a single table having all the table names used in the source query listed. I will call this table   ‘AllDemoTables’.  The below script will create this table :

CREATE TABLE AllDemoTables ( id INT identity(1,1),demotablenames VARCHAR(50))
INSERT INTO AllDemoTables
SELECT 'demo1' UNION ALL
SELECT 'demo2' UNION ALL
SELECT 'demo3'

The next step is to use an Execute SQL Task in the package, which will execute a query that returns a SingleRow resultset using the table AllDemoTables.

Use the query below in the SQL Statement of Execute SQL Task. This query is a generic query which will select the common columns from all the tables inside the ‘AllDemoTables’ and joining them with ‘UNION ALL’.

DECLARE @qry VARCHAR(max)
SELECT  @qry=COALESCE(@qry,'') +CASE WHEN ID = (SELECT MAX(id) FROM demo)
                  THEN ' '+CHAR(13)+'SELECT Rowid, Versionno FROM '+demotablenames
                  ELSE '  '+CHAR(13)+'SELECT Rowid, Versionno FROM '+demotablenames+' UNION ALL'
            END
FROM AllDemoTables
SELECT @QRY

The output of this query is shown below:


When this query is passed in Execute SQL Task, set the Result set as Single row and capture it in a String variable :


Once this is completed add a Data Flow task below the Execute SQL task.


In the OLEDB source refer to the resultset variable (qry) from Execute SQL task. For the first time, hardcode the two columns and connect the OLEDB destination.  After all the settings, execute the package.



After the package execution is successful, you can see that 9 versions for a single row from all the three tables are successfully inserted in the destination table and the table data is shown below.


Now, let us add a new table in the query.

CREATE TABLE demo4 (RowID INT, Versionno INT, demo4comments VARCHAR(50))
INSERT INTO demo4
SELECT 1,10,'demo4' UNION ALL
SELECT 1,11,'demo4'
INSERT INTO AllDemoTables
SELECT 'demo4'

I have added a new table demo4, which needs to be referred in the query. Repeating the above steps, first add the new table name in our ‘AllDemoTables’ table. The changes will be automatically taken by the package, as it is referring to AllDemoTables and building the query from the table names contained in that table.

Now, we can execute the package again. This time instead of nine rows it should transfer 11 rows. Last two Versionno are from table demo4.


Finally, we can check the data in the destination table again.


All the 11 versions have been successfully inserted into the destination table without changing the package.

There can be numerous solutions to this problem but this method was easy to implement and proved very useful in adding continuous enhancements to the product which required adding the new tables.

]]>

Leave a comment

Your email address will not be published.