This is the third in a series of posts about SSIS parent-child architecture. You can find the index page here.
In my previous posts on SSIS parent-child package architecture, I described the benefits of the parent-child package design pattern and demonstrated the implementation of such a pattern in package deployment mode. In this post, I will demonstrate the parent-child pattern for implementations using catalog deployment mode, which is the default design on SSIS 2012 and 2014.
Catalog deployment mode in SSIS
If you’re reading this post and find yourself asking, “What is catalog deployment mode?”, here it is in a nutshell: Starting with SQL Server 2012, there were significant changes to the architecture of SSIS, most notably the move to a deployment/storage structure called catalog deployment model (which is also frequently referred to as the project deployment model). In this model, SSIS code is more project-centric than package-centric; packages are deployed as an entire project instead of individually (though each package can still be executed independently). Catalog deployment mode in SSIS also brought the addition of parameters, which can be used to externally set runtime values for package executions, as well as project connections, which can be used to easily share connection settings across all packages in a project. Many other changes were introduced, including a simpler logging model and a dedicated SSIS database.
Among the many changes brought about by the catalog deployment model, the one that had the most impact on the parent-child design pattern is the addition of parameters. In older versions of SSIS, it was possible to pass runtime values to a package, but the process was clunky at best. When using SSIS 2012 or 2014 in catalog deployment mode, setting runtime values for a child package (or a standalone package, for that matter) is much easier and more straightforward than performing the same task in previous versions.
It is also worth noting that you don’t have to use the catalog deployment model in recent versions of SSIS. Although catalog deployment model is the default setting in SSIS 2012 and 2014, you can set your project to use the package deployment model. You’ll lose many of the new features (including parameterization and simplified logging) by choosing package deployment model, but this might be practical if your organization has made a significant investment in SSIS architecture that would be broken by moving to catalog deployment model.
Parent-child package execution
At the heart of parent-child architecture is the collection of parameters. In catalog deployment mode, we can set up parameters at the package level or at the project level. For values that would affect just a single package, using a package parameter would make the most sense. However, if a value might need to be shared among several (or all) packages in a particular project, a project parameter would allow you to create the parameter once for the entire project rather than one for each package.
Execute package task
When executing a child package, the simplest method is still the execute package task. Introduced in 2012, the execute package task now has a dropdown list (shown below, on the Package tab) to allow the SSIS developer to specify the target package.
There are a few limitations with this approach. Most notably, this dropdown list selection only works when calling a package that exists in the same project. You’ll notice that the selection above the package name, entitled ReferenceType, is set to Project Reference. Though you can change ReferenceType to use a project located elsewhere, oddly enough you can’t use it to execute a package in a different project deployed to the SSIS catalog (you can read more about that limitation, as well as upvote the issue on Connect here). I’ll discuss a couple of workarounds for this momentarily.
Clicking over to the Parameter bindings tab, we can specify which values to pass into the child package. For each child package parameter, we specify exactly one value to be supplied at runtime. Remember, like the dropdown list for package selection, this piece only works when executing packages in the same project (using the Project Reference setting on the ReferenceType from the Package tab).
Keep in mind that you have to use a parameter or variable (again, choosing from the dropdown list) to map to the child parameter. You can’t simply type in a static value in the Binding parameter or value field. Also, remember that you will only see package parameters (not project parameters) in the list of child package parameters that may be mapped. This is by design – it wouldn’t make sense to map a value to a project parameter when executing a package in the same project, since that child package would already implicitly have access to all of the project parameters.
Another distinct advantage of using the execute package task is the process for handling errors in the child package. In the event that a child package fails, the execute package task will fail as well. This is a good thing, because if the child package does fail, in almost all cases we would want the parent package to fail to prevent dependent tasks from improperly executing. Even better, error messages from the child package would be bubbled up to the parent package, allowing you to collect error messages from all child packages within the parent package. Consolidated error handling and logging means less development time upfront, and less maintenance effort down the road.
If you have the option of using the execute package task for starting packages stored in the SSIS catalog, I recommend sticking with this method.
Execute SQL task
Another method for executing one package from another is by using the T-SQL stored procedures in the SSIS catalog itself. Executing a package in the SSIS catalog in T-SQL is actually a 3-step process:
- Create the execution entry in the catalog
- Add in any parameter values
- Execute the package
Catalog package execution via T-SQL, another new addition in SSIS 2012, allows us to overcome the limitation in the execute package task I mentioned earlier. Using a T-SQL command (via the execute SQL task in SSIS), we can execute a package in any project. It’s certainly more difficult to do so, because we lose the convenience of having the list of available packages and parameters exposed in a dropdown list in the GUI. Here there be typing. However, being able to execute packages in other projects – and for that matter, on other SSIS catalog servers entirely – somewhat makes up for the manual nature of this method.
To execute a child package using this method, you’d create an execute SQL task and drop in the appropriate commands, which might look something like the following:
DECLARE @execution_id BIGINT EXEC [SSISDB].[catalog].[create_execution] @package_name = N'ChildPkgRemote.dtsx' ,@execution_id = @execution_id OUTPUT ,@folder_name = N'SSIS Parent-Child' ,@project_name = N'SSIS Parent-Child Catalog Deployment - Child' ,@use32bitruntime = False ,@reference_id = NULL -- Set user parameter value for filename DECLARE @filename SQL_VARIANT = N'E:\Dropbox\Presentations\_sampleData\USA_small1.txt' EXEC [SSISDB].[catalog].[set_execution_parameter_value] @execution_id ,@object_type = 30 ,@parameter_name = N'pSourceFileName' ,@parameter_value = @filename -- Set execution parameter for logging level DECLARE @loggingLevel SMALLINT = 1 EXEC [SSISDB].[catalog].[set_execution_parameter_value] @execution_id ,@object_type = 50 ,@parameter_name = N'LOGGING_LEVEL' ,@parameter_value = @loggingLevel -- Set execution parameter for synchronized DECLARE @synchronous SMALLINT = 1 EXEC [SSISDB].[catalog].[set_execution_parameter_value] @execution_id ,@object_type = 50 ,@parameter_name = N'SYNCHRONIZED' ,@parameter_value = @synchronous -- Now execute the package EXEC [SSISDB].[catalog].[start_execution] @execution_id -- Show status SELECT [status] AS [execution_status] FROM SSISDB.CATALOG.executions WHERE execution_id = @execution_id
Two things in particular I want to point out here. First of all, by default when executing a package using T-SQL, the package is started asynchronously. This means that when you call the stored procedure [SSISDB].[catalog].[start_execution], the T-SQL command will return immediately (assuming you passed in a valid package name and parameters), giving no indication of either success or failure. That’s why, on this example, I’m setting the execution parameter named SYNCHRONIZED to force the T-SQL command to wait until the package has completed execution before returning. (Note: For additional information about execution parameters, check out this post by Phil Brammer). Second, regardless of whether you set the SYNCHRONIZED parameter, the T-SQL command will not return an error even if the package fails. I’ve added the last query in this example, which will return the execution ID as well as the execution status. I can use this to check the execution status of the child package before starting any subsequent dependent tasks.
As shown, I’ve set the SQLStatement value to the T-SQL code block I listed above, and set the ResultSet value to Single row, the latter of which will allow me to capture the output status of the executed package. Below, I’ve set that execution status value to a new package variable.
To round out this design pattern, I set up my control flow as shown below. Using precedence constraints coupled with SSIS expressions, I execute the package and then check the return value: a successful catalog execution returns a value of 7, and my parent package handles any return value other than a 7 as a failure.
You may also have to give special consideration for errors in child packages when using T-SQL for package execution – especially when running packages interactively in the BIDS/SSDT designer. Since the T-SQL command does not report the failure of a package by default, it also doesn’t “bubble up” errors in the traditional SSIS manner. Therefore, you’ll need to rely on capturing any child package error messages from the SSIS catalog logging tables, especially when developing and testing packages in Visual Studio.
It is also possible to execute SSIS packages programmatically from the script task. This method is significantly more complicated, but also offers a great deal of flexibility. A fellow SQL Server MVP and acquaintance of mine, Joost van Rossum, has a detailed blog post on how to programmatically execute SSIS packages from the SSIS script task. I won’t restate what he has already covered in his comprehensive and well-written post on the topic, but if you need to programmatically fire child packages in the SSIS catalog, check out his write-up.
In this post, I’ve covered the essentials of executing child packages in the SSIS catalog, including provisioning for errors in the child package. Though it can be quirky, especially when executing child packages in a different project or on a different server, there are several different ways to address this parent-child design pattern.
In my next post, I’ll talk a little more about passing values in a parent-child package, and will illustrate how to pass values from child packages back to the parent package.