Categories
SSIS

Wrestling with Temp Tables in SSIS Data Sources

When handing data we can make use of temporary tables to aid with separation or performance. However, they don’t always play nice with Integration Services packages.

If we set a source to call a procedure returning the contents of a temporary table we’ll see an error like below:

Exception raised when using a stored procedure in a data source which uses a temporary table

The process is unable to determine the metadata for an object that doesn’t exist. Similarly, it causes an issue when calling the proc sp_describe_first_result_set on the server itself:

EXEC sp_describe_first_result_set
	@tsql = N'EXEC dbo.OrderReportData;';

The metadata could not be determined because statement ‘SELECT * FROM #Results’ in procedure ‘OrderReportData’ uses a temp table.

Options

There are a few approaches which we could take to alleviate the issue:

  • Rework the procedure – to avoid the use of temporary tables, for example using one large query, or combining with sub queries or CTEs. This may have a performance impact on the SQL side
  • Move the processing into the package – using existing features within SSIS to combine, filter, and manipulate the data, removing logic from the procedure. This will impact performance of the SSIS package
  • Stage the results – put the results into a persistent table which the package can reliably reference

My preferred option is the third one. It has minimal impact on both the SQL code and SSIS package. This means not only less effort, but less chance of impacting behaviour or performance as a result.

Staging the data

Staging the data is simple. Instead of outputting via a SELECT we will INSERT into a new staging table. This table will then be used by the package to read the data.

Firstly let’s create a staging schema for the table if we don’t already have one:

IF NOT EXISTS (
	SELECT 'exists'
	FROM sys.schemas
	WHERE [name] = 'stg'
)
BEGIN
	EXEC ('CREATE SCHEMA [stg]
		AUTHORIZATION [dbo];');
END

Now we can create our staging table which should mirror the output from the procedure:

CREATE TABLE [stg].[ReportResults] (
	OrderID INT,
	OrderDate DATETIME,
	CustomerName VARCHAR(100),
	ProductName VARCHAR(100),
	OrderQuantity INT
);

Next up, its updating the procedure. Firstly don’t forget to clear the contents of the temporary table before you populate it:

TRUNCATE TABLE [stg].[ReportResults];

Then we need to finish the proc inserting the data which would normally be returned from our temporary table. A basic example would be:

INSERT INTO [stg].[ReportResults] (
	OrderID,
	OrderDate,
	CustomerName,
	ProductName,
	OrderQuantity
)
SELECT *
FROM #Results;

Modifying the package

Now that we’ve got a procedure which is staging the data, we need to call the procedure to populate the table, and then read the data as separate processes.

First up we’ll add a new Execute SQL Task step prior to the data flow where we’re reading it. This will now call the procedure and populate the staging table:

Configuration for an Execute SQL Task step to call the procedure

Finally we need to change the source reader to use the staging table instead of calling the procedure:

Data source configured to use the staging table directly instead of a stored procedure

As we now have a table in the database, this will mean no ambiguity with the results. This will allow the package to read the metadata and we can map this in the data flow.

Wrap up

In this post we’ve seen how the use of temporary tables in procedures can impact SSIS when trying to use their output as a data source.

We’ve highlighted a few ways to combat this challenge, and worked through my preferred option to separate the processing of the data from the reading of it.

This approach requires some modification on both the SQL and SSIS sides of the process, but the changes are relatively minor. Due to this, the potential for performance impact is minimised compared to the alternatives.

One reply on “Wrestling with Temp Tables in SSIS Data Sources”

Leave a reply to Temp Tables in SSIS Data Sources – Curated SQL Cancel reply