SQL Server Integration Services: The Complete DBA and Developer Guide

SQL Server Integration Services: The Complete DBA and Developer Guide | SQLYARD

SQL Server Integration Services: The Complete DBA and Developer Guide


SQL Server 2019
SQL Server 2022
SQL Server 2025

SQL Server Integration Services (SSIS) is Microsoft’s on-premises ETL and data integration platform. It ships as a component of SQL Server and runs packages — XML-based workflow files that extract data from sources, apply transformations, and load results into destinations. SSIS has been the foundation of enterprise ETL on the Microsoft stack since SQL Server 2005, when it replaced the older Data Transformation Services (DTS). SQL Server 2012 added the SSISDB catalog, which transformed how packages are deployed, parameterized, monitored, and secured.

This guide covers SSIS from the ground up: what every component does, how the package execution engine works, every major task and transformation type, deployment models, the SSISDB catalog internals, connection manager patterns, monitoring queries, checkpoints, SQL Server 2025 changes, and how to configure SSISDB for high availability with Always On Availability Groups.

SQL Server 2025 removes several SSIS components. Read Section 17 before upgrading. The Microsoft Connector for Oracle, CDC components by Attunity, and Hadoop tasks are removed in SQL Server 2025. The Legacy SSIS Service and 32-bit execution mode are deprecated. If any existing packages use these components, migration planning is required before upgrading.
1

What SSIS Is and Where It Fits

Beginner

SSIS sits between source systems (databases, flat files, APIs, cloud services) and destination systems (data warehouses, staging databases, reporting stores). It handles the extract, transform, and load (ETL) operations that move and shape data on a schedule or triggered by an event.

SSIS is not a database. It does not store data permanently. It is a pipeline engine: packages read from sources, process data through in-memory buffers, apply transformations, and write to destinations. The package itself is an XML file with a .dtsx extension containing the complete definition of every connection, task, transformation, variable, and configuration.

ComponentRole
SSIS Runtime EngineControls package execution order, manages containers, handles events, applies logging, manages transactions and checkpoints
SSIS Data Flow Engine (pipeline engine)Manages in-memory buffer allocation, moves data between sources and destinations, applies transformations within a Data Flow task
SSIS Designer (Visual Studio extension)Graphical development environment for building packages. Packages are created and edited here only — SSMS does not have a package designer.
SSISDB CatalogSQL Server database that stores deployed projects, packages, parameters, environments, and execution history
dtexec.exeCommand-line utility for executing packages from the file system, MSDB, or SSISDB catalog
ISServerExec.exeServer-side execution process used when packages are executed through the SSISDB catalog
SSIS packages are built in Visual Studio, not SSMS. Visual Studio 2022 with the SQL Server Integration Services Projects 2022 extension is required to create and edit SSIS packages. SSMS is used for deploying, executing, monitoring, and managing packages already in the SSISDB catalog. These are distinct tools with distinct roles.
2

Package Anatomy: The Five Designer Tabs

Beginner

When a package is open in Visual Studio, the SSIS Designer shows five tabs. Each tab exposes a different aspect of the package.

TabWhat It ShowsWhat Is Configured Here
Control FlowThe workflow of the package: which tasks run, in what order, under what conditionsTasks, containers, precedence constraints, annotations
Data FlowThe data pipeline inside a Data Flow task: how data moves from sources through transformations to destinationsSources, transformations, destinations, error output paths
Event HandlersCustom workflows that fire in response to package and task eventsOnError, OnTaskFailed, OnWarning, OnPreExecute, OnPostExecute handlers
Package ExplorerA tree view of all package objects: connection managers, event handlers, executables, log providers, precedence constraints, variablesRead-only overview; double-click objects to edit
ParametersPackage-level parameters that can be passed in at runtime to change behavior without editing the packageCreate, name, type, and set default values for package parameters
3

The Two Execution Engines

Intermediate

SSIS uses two separate engines that operate at different layers of a package.

The Runtime Engine manages everything in the Control Flow layer: it sequences tasks and containers, evaluates precedence constraints, fires event handlers, manages transactions, applies logging, and implements checkpoints. It processes one task at a time (or multiple tasks in parallel when configured) and tracks the overall package execution state.

The Data Flow Engine (pipeline engine) manages the Data Flow task layer: it allocates in-memory buffers, moves data between components, applies transformations, and writes to destinations. The pipeline engine uses a buffered execution model — data moves through the pipeline in batches (buffers) rather than row by row, which is why SSIS can process millions of rows efficiently. The buffer size is controlled by the DefaultBufferMaxRows and DefaultBufferSize properties on the Data Flow task.

Buffer spill to disk is automatic but expensive. When the pipeline engine cannot fit all buffers in memory, it spills temporary buffer files to the directory specified in BufferTempStoragePath (defaults to the system temp directory). Buffer spill dramatically reduces throughput. If execution logs show high disk I/O during package runs, check available memory and adjust DefaultBufferSize or add RAM to the server.
4

Control Flow: Tasks, Containers, and Precedence Constraints

Beginner

The Control Flow defines what a package does and in what order. It is built from three types of objects.

Tasks are the individual units of work: run a SQL statement, move a file, send an email, execute a data flow. Each task is an independent executable that succeeds or fails and returns a completion state to the runtime engine.

Containers group tasks and control execution flow: loop over a set of files, repeat a block of tasks a fixed number of times, or group tasks for transaction management. Containers can nest inside each other.

Precedence Constraints connect tasks and containers and define the conditions under which the next object executes. A constraint can be based on the outcome of the previous task (success, failure, or completion regardless of outcome), on the value of a variable or expression, or on a combination of both.

Precedence Constraint TypeBehavior
SuccessThe downstream object executes only if the upstream object succeeded. Default for new connections.
FailureThe downstream object executes only if the upstream object failed. Used for error handling workflows.
CompletionThe downstream object always executes regardless of whether the upstream object succeeded or failed.
ExpressionThe downstream object executes only when a SSIS expression evaluates to true, independent of task outcome.
Expression and ConstraintBoth the outcome condition AND the expression must be true for the downstream object to execute.
Expression or ConstraintEither the outcome condition OR the expression being true causes the downstream object to execute.
5

Built-In Tasks

Beginner
TaskWhat It Does
Data Flow TaskHosts the entire data pipeline: sources, transformations, and destinations. The most commonly used task in ETL packages. Each package can have multiple Data Flow tasks.
Execute SQL TaskRuns one or more T-SQL or ANSI SQL statements against any database accessible through a connection manager. Can capture single-row or full result sets into SSIS variables.
Execute Package TaskCalls another SSIS package and waits for it to complete. Used to break large solutions into modular parent-child package hierarchies.
Script TaskRuns custom C# or VB.NET code in the control flow. Used for operations that no built-in task covers: calling REST APIs, custom file operations, complex conditional logic.
File System TaskCopies, moves, renames, deletes files and directories. Operates on the Windows file system using paths defined in Flat File or File connection managers.
Send Mail TaskSends email via SMTP. Uses a SMTP connection manager. Typically used in event handlers to notify on failure, not in the main control flow.
FTP TaskTransfers files to and from FTP servers. Supports file send, receive, create directory, remove directory, and delete operations.
Web Service TaskCalls a SOAP web service method and can store the result in a variable or file. Does not support REST — use Script Task for REST API calls.
Execute Process TaskRuns an external executable or batch file and waits for it to complete. Can capture the process exit code into a variable.
Bulk Insert TaskPerforms a fast bulk insert from a flat file into a SQL Server table using the same engine as T-SQL BULK INSERT. Faster than the OLE DB Destination for large file loads but less flexible.
Analysis Services Execute DDL TaskExecutes XMLA DDL commands against an Analysis Services instance: process cube, create database, alter partition.
Analysis Services Processing TaskProcesses Analysis Services objects: databases, cubes, dimensions, partitions.
XML TaskPerforms XML operations: validate, merge, diff, patch, query with XPath, transform with XSLT.
Message Queue TaskSends and receives MSMQ messages. Legacy task; rarely used in modern implementations.
6

Containers

Beginner
ContainerWhat It DoesCommon Use
Sequence Container Groups tasks and containers into a logical unit with a shared transaction scope and a single success/failure state. Does not loop. Grouping related tasks (all dimension loads in one container, all fact loads in another) for transaction management and visual organization
For Loop Container Repeats the tasks inside it a fixed number of times based on an initializer expression, a condition expression, and an assignment expression — equivalent to a for loop in code. Processing a fixed number of iterations where the count is known at design time or stored in a variable
Foreach Loop Container Iterates over a collection and executes the tasks inside for each member. The collection is defined by an enumerator type. Processing all files in a folder (Foreach File enumerator), iterating over rows in a result set (Foreach ADO enumerator), looping over items in a variable (Foreach Item enumerator)
Task Host Container An implicit container that wraps every task. Not visible in the designer. Provides the task with a variable scope, transaction context, and event handling capability. Internal implementation detail; not configured directly by developers
Foreach Loop enumerator types verified against Microsoft Learn: Foreach File, Foreach Item, Foreach ADO, Foreach ADO.NET Schema Rowset (deprecated in SQL Server 2025), Foreach From Variable, Foreach NodeList (XPath over XML), Foreach SMO (deprecated in SQL Server 2025), Foreach HDFS File (removed in SQL Server 2025), Foreach Azure Blob (Azure Feature Pack).
7

Event Handlers

Intermediate

Event handlers are mini control flows that execute in response to events raised by the package, containers, or tasks at runtime. They have the same structure as the package control flow — they can contain tasks and containers connected by precedence constraints — but they execute only when a specific event fires.

EventFires WhenCommon Use
OnErrorAn error occurs in the executable that owns the handlerSend failure notification email; write error details to a log table; roll back custom state
OnTaskFailedA task failsSame as OnError but specifically for task failures; can be defined at the task level rather than package level
OnWarningA warning is raisedLog warnings to a table; send email when data quality warnings exceed a threshold
OnPreExecuteImmediately before an executable startsLog execution start time; validate preconditions; set runtime variables
OnPostExecuteImmediately after an executable completes (regardless of outcome)Log execution end time; clean up temporary files; update processing status tables
OnProgressProgress information is reported during executionCustom progress monitoring
OnVariableValueChangedA variable with RaiseChangeEvent set to true changes valueReact dynamically to variable value changes during execution

Event handlers propagate up the container hierarchy by default. If a task raises an OnError event and the task has no OnError handler, the event propagates to the task’s parent container, then to the package. The first handler found in the hierarchy handles the event.

8

Data Flow Architecture

Intermediate

The Data Flow task hosts a separate execution graph from the control flow. Inside a Data Flow task, components are connected by data paths (green arrows) that carry columns of data between components. The pipeline engine allocates memory buffers, fills them with rows from sources, passes them through transformation components, and delivers them to destinations.

Components in a data flow are classified by their relationship to data:

  • Sources read data from external systems and introduce it into the pipeline as rows and columns.
  • Transformations receive rows from upstream components, apply operations (modify values, filter rows, look up reference data, split or merge streams), and pass results downstream.
  • Destinations consume rows from the pipeline and write them to external systems.

Transformations are further classified by whether they are synchronous (process one row at a time, same buffer, no additional memory) or asynchronous (must collect rows before producing output, requires a new buffer, higher memory usage). Sorting and aggregating are asynchronous because they cannot produce output until all input rows have been received. Derived Column and Conditional Split are synchronous because each input row immediately produces output.

9

Sources

Beginner
Source ComponentReads FromNotes
OLE DB SourceSQL Server, Oracle, Access, and any OLE DB providerSupports table, view, or SQL query mode. Most commonly used source for SQL Server data.
ADO.NET SourceAny .NET data providerRequired for SQL Server 2025 packages with the new Microsoft.Data.SqlClient provider; preferred over OLE DB for modern deployments
Flat File SourceDelimited, fixed-width, or ragged-right text filesReads one file per execution. Use Foreach Loop to iterate over multiple files.
Excel SourceMicrosoft Excel workbooks (.xls, .xlsx)Requires the ACE OLE DB provider installed on the SSIS server. 64-bit driver required for 64-bit execution.
XML SourceXML filesGenerates output based on the XSD schema. Complex XML requires custom mapping.
Raw File SourceSSIS raw file format written by Raw File DestinationFastest read format; no parsing overhead. Only readable by SSIS itself.
Script Component (source mode)Any source code can accessC# or VB.NET code generates rows. Used for REST APIs, custom file formats, or any source no built-in component supports.
10

Transformations

Intermediate
TransformationWhat It DoesSync/Async
Derived ColumnAdds new columns or replaces existing column values using SSIS expressions. The most commonly used transformation for data manipulation.Synchronous
Conditional SplitRoutes rows to different output paths based on conditions — equivalent to an IF/ELSE or CASE statement applied to data flow rows.Synchronous
LookupJoins each pipeline row to a reference dataset (from a database table, cache, or raw file) on one or more key columns. Returns matched or unmatched rows to different outputs.Synchronous (full cache mode); Asynchronous characteristics apply in partial/no cache mode
Merge JoinPerforms INNER, LEFT OUTER, or FULL OUTER joins on two sorted input streams. Both inputs must be sorted on the join key columns before entering Merge Join.Synchronous
SortSorts all rows on one or more columns. Must accumulate all rows before producing sorted output — high memory usage for large datasets. If the source can sort (SQL ORDER BY), prefer that over this transformation.Asynchronous (blocking)
AggregateGroups rows and computes aggregates: SUM, COUNT, AVG, MIN, MAX, COUNT DISTINCT. Must accumulate all rows in the group before producing output.Asynchronous (blocking)
Data ConversionConverts a column from one data type to another. Produces a new column — the original is preserved. Rename the output column and drop the original if the original name is needed.Synchronous
Character MapApplies string function mappings: uppercase, lowercase, byte reversal, simplified/traditional Chinese character mapping, Hiragana/Katakana.Synchronous
Copy ColumnCreates a copy of one or more columns in the pipeline buffer. Useful when a column needs to be used in different downstream paths with different transformations applied.Synchronous
MulticastSends a copy of every row to multiple outputs. Used when the same data needs to be delivered to more than one destination.Synchronous
Union AllCombines multiple input streams into one output stream. Does not sort or deduplicate — equivalent to UNION ALL in SQL.Asynchronous (partially blocking)
MergeCombines two sorted input streams into one sorted output stream. Both inputs must already be sorted on the same key. Use Union All when sorting is not required.Asynchronous (partially blocking)
PivotConverts rows into columns — unpivots a normalized dataset into a wide format. Requires the pivot column values to be known at design time.Asynchronous (blocking)
UnpivotConverts wide-format column data into rows. Normalizes data from a denormalized source format.Synchronous
Row CountCounts rows passing through the pipeline and stores the count in a variable. Zero impact on throughput.Synchronous
Script Component (transformation mode)Custom C# or VB.NET transformation logic. Used when no built-in transformation covers the requirement.Synchronous or Asynchronous depending on implementation
Fuzzy LookupPerforms approximate (fuzzy) matching against a reference table — matches despite typos, misspellings, or slight variations. Slower than exact Lookup; best for data cleansing scenarios.Asynchronous
Fuzzy GroupingGroups rows that appear to be duplicates based on fuzzy matching. Returns a canonical representative for each group.Asynchronous (blocking)
Cache TransformWrites data from the pipeline to a Cache connection manager’s in-memory or file cache. The cached data is then referenced by a Lookup transformation configured to use cache mode.Asynchronous
11

Destinations

Beginner
Destination ComponentWrites ToNotes
OLE DB DestinationSQL Server and any OLE DB targetSupports fast load (bulk insert) and row-by-row insert. Fast load mode is significantly faster for large volumes but acquires a table lock. Row-by-row mode allows concurrent writes.
ADO.NET DestinationAny .NET data provider targetPreferred for SQL Server 2025 with Microsoft.Data.SqlClient. More flexible than OLE DB for modern authentication scenarios.
Flat File DestinationDelimited or fixed-width text filesOverwrites or appends to the file. One file per execution — combine with Foreach Loop for multiple output files.
Excel DestinationMicrosoft Excel workbooksRequires the same ACE OLE DB driver as Excel Source. Limited to 65,535 rows in older .xls format.
Raw File DestinationSSIS raw file formatFastest write format. Used as a checkpoint or intermediate store between pipeline stages. Only readable by SSIS Raw File Source.
SQL Server DestinationSQL Server on the same machine as the packageUses shared memory for maximum throughput — fastest local SQL Server destination. Deprecated in SQL Server 2025; migrate to OLE DB Destination or ADO.NET Destination.
SQL Server Compact DestinationSQL Server Compact databasesLegacy. SQL Server Compact is end-of-life. Do not use in new implementations.
Script Component (destination mode)Any target code can write toCustom write logic in C# or VB.NET. Used for REST API targets, custom file formats, or targets no built-in component supports.
SQL Server Destination is deprecated in SQL Server 2025. The SDS (SQL Server Destination) connection type is deprecated in SQL Server 2025. Migrate existing packages using SQL Server Destination to OLE DB Destination with the SQL Server OLE DB provider, or to ADO.NET Destination with the Microsoft.Data.SqlClient provider.
12

Error Outputs

Intermediate

Most data flow components support an error output — a secondary output path that receives rows that fail processing in that component. Each error output row includes two additional columns: ErrorCode (a negative integer identifying what went wrong) and ErrorColumn (the lineage ID of the column that caused the error).

Error output behavior is configurable per component and per column. The options are: Fail Component (the entire data flow task fails on the first error), Ignore Failure (the row continues to the standard output as if no error occurred), and Redirect Row (the row is sent to the error output instead of the standard output).

-- Look up the column name from ErrorColumn lineage ID at design time
-- SSIS expression to get a readable description:
-- Use the SSIS function in Script Component:
-- ComponentMetaData.GetErrorDescription(ErrorCode)
-- ComponentMetaData.GetErrorColumnDescription(ErrorColumn, ErrorCode)

-- In the Script Component reading the error output, add this to the Input0_ProcessInputRow method:
-- Row.ErrorDescription = ComponentMetaData.GetErrorDescription(Row.ErrorCode);
13

Variables, Parameters, and Expressions

Intermediate

Variables

Variables store values that change at runtime. They are scoped to the object that defines them — a package-level variable is visible to all tasks; a container-level variable is only visible within that container. Variables are read and written by tasks (Execute SQL Task can map query results to variables), by expressions, and by Script Tasks.

Parameters

Parameters are values passed into a package from outside at execution time. They are read-only inside the package. Package parameters are defined at the package level. Project parameters are defined at the project level and shared across all packages in the project.

ConceptScopeWritable at RuntimePassed From Outside
VariablePackage, container, or taskYes — tasks and expressions can write to variablesNo — set inside the package or via package configuration
Package ParameterPackageNo — read-only during executionYes — passed at execution time via SSISDB environment or dtexec command line
Project ParameterAll packages in the projectNo — read-only during executionYes — bound to SSISDB environment variables

Expressions

SSIS expressions are a formula language used to dynamically set property values at runtime. Expressions can reference variables, parameters, system variables, and functions. They are evaluated when the package starts (for most properties) or at each iteration (for properties inside loops).

-- Common expression examples

-- Dynamic file path using today's date (set on Flat File Connection Manager's ConnectionString property)
@[User::FilePath] + "sales_" + (DT_STR, 4, 1252) DATEPART("yyyy", GETDATE())
+ RIGHT("0" + (DT_STR, 2, 1252) DATEPART("mm", GETDATE()), 2)
+ RIGHT("0" + (DT_STR, 2, 1252) DATEPART("dd", GETDATE()), 2) + ".csv"

-- Conditional precedence constraint expression: only proceed if row count > 0
@[User::RowCount] > 0

-- Dynamic SQL in Execute SQL Task CommandText property
"SELECT * FROM " + @[$Project::SourceSchema] + ".Orders WHERE LoadDate = '"
+ (DT_STR, 10, 1252) @[User::ProcessDate] + "'"
14

Connection Managers

Beginner

Connection managers store connection information: server names, credentials, file paths, and provider settings. They are separate from the tasks and components that use them, so the same connection can be shared across multiple tasks without duplicating configuration. Connection managers exist at two scopes.

ScopeVisible ToBest For
Package-levelAll tasks and components within one packageConnections used only within a single package
Project-levelAll packages in the projectShared connections: the source database, the destination warehouse, a shared SMTP server

Connection strings in connection managers can be parameterized using project or package parameters, so the same package connects to the development database in one SSISDB environment and the production database in another without any package modification.

-- Bind a project-level connection manager's ConnectionString to an SSISDB environment variable
EXEC catalog.set_object_parameter_value
    @object_type = 20,            -- 20 = project
    @folder_name = N'ETL',
    @project_name = N'SalesETL',
    @parameter_name = N'CM.SourceDB.ConnectionString',
    @parameter_value = N'DbConnString',
    @value_type = 'R';            -- R = reference to environment variable
GO
15

Checkpoints

Intermediate

Checkpoints allow a failed package to restart from the point of failure rather than from the beginning. When checkpoints are enabled, SSIS writes a checkpoint file after each successfully completed task. If the package fails and is re-executed, SSIS reads the checkpoint file and skips all previously completed tasks, resuming from the first task that did not complete successfully.

-- Checkpoint properties set on the Package object (not a task)
-- In Visual Studio, select the package background and set these in the Properties window:

-- CheckpointFileName: path to the checkpoint file
-- "C:\SSISCheckpoints\SalesLoad.dtsx.chk"

-- CheckpointUsage: options are
-- Never (default) - checkpoints not used
-- IfExists - use checkpoint file if it exists; start fresh if it does not
-- Always - checkpoint file must exist; fail if it does not exist

-- SaveCheckpoints: True to write the checkpoint file; False to read only
Checkpoints have important limitations. Checkpoints do not work with the Foreach Loop Container or the For Loop Container — these containers cannot be checkpointed. The checkpoint file stores state for the package-level control flow only. Tasks inside a loop that completed in a previous run will re-execute in a restart because the loop itself restarts. Checkpoints also do not work for packages that use transactions spanning the full package.
16

Deployment Models: File System, MSDB, SSISDB

Beginner

SSIS packages can be deployed and stored in three locations. The correct choice for any new implementation is SSISDB.

ModelStorageExecutionLoggingVersioning
File System .dtsx files on disk or a UNC share dtexec /f or SQL Agent CmdExec job step Optional log providers (flat file, event log, SQL Server table) Manual — no built-in versioning
MSDB (Legacy Package Store) msdb.dbo.sysssispackages in the SQL Server database dtexec /SQL or SQL Agent SSIS Package step Same optional log providers as file system None
SSISDB Catalog (Project Deployment) SSISDB database — projects deployed as .ispac files SQL Agent Integration Services Package step or catalog.start_execution Built-in automatic logging to catalog views Automatic — each deployment creates a new version; rollback available
Legacy SSIS Service (MSDB Package Store) is deprecated in SQL Server 2025. The SSIS Service that enables storage and monitoring of packages in the MSDB database is deprecated in SQL Server 2025. It is still installed but should be disabled. Packages stored in MSDB should be migrated to the SSISDB catalog (project deployment model) before upgrading to SQL Server 2025.
-- Deploy an ISPAC file to SSISDB using T-SQL
-- First create the catalog if it does not exist (requires CLR enabled)
EXEC catalog.create_catalog
    @catalog_password = 'YourStrongPassword';
GO

-- Create a folder
EXEC catalog.create_folder
    @folder_name = N'ETL';
GO

-- Deploy from file using PowerShell (most common approach):
-- $env = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Management.IntegrationServices")
-- $conn = New-Object Microsoft.Data.SqlClient.SqlConnection "Server=.;Integrated Security=SSPI;Encrypt=True;TrustServerCertificate=True;"
-- $ssis = New-Object Microsoft.SqlServer.Management.IntegrationServices.IntegrationServices $conn
-- $catalog = $ssis.Catalogs["SSISDB"]
-- $folder = $catalog.Folders["ETL"]
-- $ispac = [System.IO.File]::ReadAllBytes("C:\Projects\SalesETL\bin\Development\SalesETL.ispac")
-- $folder.DeployProject("SalesETL", $ispac)
17

SQL Server 2025 Changes

Advanced
ChangeTypeImpact and Action
Microsoft Connector for Oracle Removed No longer available from SQL Server 2025 SSIS. Support ended July 4, 2025. Migrate Oracle connections to ADO.NET components, or migrate the integration to Azure Data Factory or Microsoft Fabric Data Factory.
CDC components by Attunity Removed CDC components and CDC service for Oracle by Attunity are discontinued in SQL Server 2025. Support ended December 13, 2025. Migrate to Azure Data Factory or custom CDC implementations using SQL Server CDC feature.
Hadoop tasks Removed Hadoop Hive Task, Hadoop Pig Task, and Hadoop File System Task are removed. Migrate to Azure Data Factory or Spark-based pipelines.
Legacy SSIS Service (MSDB Package Store) Deprecated The service that enables MSDB package storage is deprecated. Still installed in SQL Server 2025 but should be disabled. Migrate packages to SSISDB catalog.
32-bit execution mode Deprecated SSIS 32-bit execution is deprecated. SSMS 21 and Integration Services Projects 2022+ are 64-bit only. Review any packages relying on 32-bit-only OLE DB providers or ODBC drivers and source 64-bit replacements.
SDS (SQL Server Destination) connection type Deprecated Replace with OLE DB Destination or ADO.NET Destination.
Foreach ADO.NET Schema Rowset Enumerator Deprecated Migrate to alternative enumeration patterns.
Foreach SMO Enumerator Deprecated Migrate to alternative enumeration patterns.
ADO.NET Connection Manager: Microsoft SqlClient provider New feature ADO.NET connection manager now supports Microsoft.Data.SqlClient, enabling TLS 1.3, Strict Encryption, and Microsoft Entra ID authentication. Update connection managers in new packages to use this provider.
.NET API breaking change Breaking change The Microsoft.SqlServer.Management.IntegrationServices constructor now requires Microsoft.Data.SqlClient.SqlConnection instead of System.Data.SqlClient.SqlConnection. Update all PowerShell and C# deployment automation scripts before upgrading to SQL Server 2025.
18

SSISDB Catalog Internals

Intermediate

The SSISDB catalog is a SQL Server database installed on the same instance as the SSIS service. It organizes content in a four-level hierarchy: Catalog → Folder → Project → Package. Environments store named variable sets that are bound to project or package parameters to support multiple deployment targets (Dev, QA, Production) from a single deployed project.

Catalog ViewContains
catalog.foldersAll folders in SSISDB
catalog.projectsAll deployed projects with version information
catalog.packagesAll packages within deployed projects
catalog.environmentsAll environments and their parent folders
catalog.environment_variablesVariables defined within each environment
catalog.executionsAll execution records: status, timing, executed by, parameter values used
catalog.event_messagesDetailed messages for each execution: errors, warnings, informational events, task-level messages
catalog.operation_messagesOperation-level messages for deployments, validations, and executions
catalog.executable_statisticsPer-task execution timing for each package run
-- Recent executions with status and duration
USE SSISDB;
GO

SELECT
    e.execution_id,
    e.folder_name,
    e.project_name,
    e.package_name,
    e.executed_as_name,
    e.start_time,
    e.end_time,
    DATEDIFF(SECOND, e.start_time, e.end_time)  AS duration_seconds,
    CASE e.status
        WHEN 1 THEN 'Created'
        WHEN 2 THEN 'Running'
        WHEN 3 THEN 'Cancelled'
        WHEN 4 THEN 'Failed'
        WHEN 5 THEN 'Pending'
        WHEN 6 THEN 'Ended Unexpectedly'
        WHEN 7 THEN 'Succeeded'
        WHEN 8 THEN 'Stopping'
        WHEN 9 THEN 'Completed'
    END                                          AS status_description
FROM catalog.executions e
ORDER BY e.start_time DESC;
GO
-- Error messages for the most recent failed execution
USE SSISDB;
GO

DECLARE @execution_id BIGINT = (
    SELECT TOP 1 execution_id
    FROM catalog.executions
    WHERE status = 4   -- 4 = Failed
    ORDER BY start_time DESC
);

SELECT
    em.message_time,
    em.message_source_name,
    em.package_path,
    em.message
FROM catalog.event_messages em
WHERE em.operation_id = @execution_id
  AND em.event_name   = 'OnError'
ORDER BY em.message_time;
GO
19

Monitoring and Execution Logs

Intermediate

SSISDB automatically captures execution history without any log provider configuration. The logging level (set on the SQL Agent job step or via catalog.set_execution_parameter_value) controls the detail captured.

Logging LevelValueWhat Is Captured
None0No messages logged
Basic1Errors, warnings, and task-level start/end events (default)
Performance2Basic plus data flow pipeline statistics (rows read, rows written per component)
Verbose3All messages including diagnostic and progress events
-- Per-task execution statistics for a specific execution
-- Shows which task in a long-running package consumed the most time
USE SSISDB;
GO

SELECT
    es.execution_id,
    es.execution_path,
    es.start_time,
    es.end_time,
    DATEDIFF(MILLISECOND, es.start_time, es.end_time)  AS duration_ms
FROM catalog.executable_statistics es
WHERE es.execution_id = <your_execution_id>
ORDER BY duration_ms DESC;
GO
20

SSISDB Security and Roles

Intermediate
RolePermissions
ssis_adminFull control of the SSISDB catalog: deploy, execute, delete, manage permissions, view all execution history and logs
ssis_logreaderRead-only access to all execution logs and catalog views. Cannot deploy, execute, or modify packages.
Object-level permissionsGranular permissions on specific folders, projects, or packages granted via catalog.grant_permission. Allows giving a service account execute permission on one specific project without broader access.
-- Grant execute permission on a specific project to a SQL login
USE SSISDB;
GO

EXEC catalog.grant_permission
    @object_type    = 3,               -- 3 = project
    @object_id      = (SELECT project_id FROM catalog.projects WHERE name = 'SalesETL'),
    @principal_id   = DATABASE_PRINCIPAL_ID('ETLServiceAccount'),
    @permission_type = 1;              -- 1 = Read, 2 = Modify, 3 = Execute, 4 = Manage permissions, 100 = Read object
GO
21

Always On Availability Groups with SSISDB

Advanced

SSISDB is a user database under the hood. It can be added to a SQL Server Always On Availability Group like any other user database, providing automatic failover of the SSIS catalog to a secondary replica. When SSISDB fails over, all deployed projects, packages, environments, and execution history on the primary are immediately available on the new primary.

SSISDB has a requirement unique among user databases. SSISDB uses CLR and contains an encryption master key. After adding SSISDB to an AG and on every secondary replica, the SSISDB master key must be backed up and the same key opened on each replica. Without this step, the new primary after failover cannot decrypt stored credentials and sensitive parameter values.

Prerequisites

  • SQL Server Enterprise or Developer edition on all AG nodes
  • SSIS installed on the primary replica node (does not need to be installed on secondary replicas for AG membership — only the SSISDB database needs to be present)
  • CLR integration enabled on all nodes
  • An Always On Availability Group already configured with a listener
-- Step 1: Enable CLR on all nodes
EXEC sp_configure 'clr enabled', 1;
RECONFIGURE;
GO

-- Step 2: On the primary replica, create the SSISDB catalog if not already created
-- In SSMS: right-click Integration Services Catalogs > Create Catalog
-- Enable CLR integration, set a password

-- Step 3: Back up the SSISDB master key
USE SSISDB;
GO
BACKUP MASTER KEY
TO FILE = 'C:\SSISKeys\SSISDBMasterKey.key'
ENCRYPTION BY PASSWORD = 'YourKeyBackupPassword';
GO

-- Step 4: Add SSISDB to the Availability Group
ALTER AVAILABILITY GROUP [YourAGName]
ADD DATABASE SSISDB;
GO

-- Step 5: On each secondary replica, restore and open the master key
-- Copy the master key backup file to each secondary node first, then:
USE SSISDB;
GO
RESTORE MASTER KEY
FROM FILE = 'C:\SSISKeys\SSISDBMasterKey.key'
DECRYPTION BY PASSWORD = 'YourKeyBackupPassword'
ENCRYPTION BY PASSWORD = 'YourNewSecondaryPassword'
FORCE;
GO

-- Open the master key using the service master key for automatic decryption
ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY;
GO
Always connect to SSISDB using the AG listener name, not a node name. All SSIS deployments, catalog queries, and SQL Agent job steps that execute SSIS packages must use the AG listener name as the server address. If a node name is used, the connection fails after failover because the node is no longer the primary. Update all connection strings, deployment scripts, and Agent job step server references to the listener name.
-- Step 6: Verify SSISDB is in the AG and synchronized
SELECT
    ag.name                     AS ag_name,
    drs.database_id,
    DB_NAME(drs.database_id)    AS database_name,
    drs.synchronization_state_desc,
    drs.synchronization_health_desc
FROM sys.dm_hadr_database_replica_states  drs
JOIN sys.availability_groups               ag  ON drs.group_id = ag.group_id
WHERE DB_NAME(drs.database_id) = 'SSISDB';
GO
-- Step 7: Test failover and confirm SSIS execution after failover
-- In SSMS on the primary: right-click the AG > Failover
-- After failover, execute a package using the listener name:

DECLARE @execution_id BIGINT;

EXEC SSISDB.catalog.create_execution
    @folder_name   = N'ETL',
    @project_name  = N'SalesETL',
    @package_name  = N'LoadDimCustomer.dtsx',
    @execution_id  = @execution_id OUTPUT;

EXEC SSISDB.catalog.start_execution
    @execution_id = @execution_id;

-- Monitor:
SELECT execution_id, status, start_time, end_time
FROM SSISDB.catalog.executions
WHERE execution_id = @execution_id;
GO

Workshop 1: Build and Deploy a Package to SSISDB

Prerequisites

Visual Studio 2022 with Integration Services Projects extension, SQL Server 2019 or later with SSIS and SSISDB configured, SSMS.

Step 1: Create the project

Open Visual Studio 2022. File → New → Project. Search for “Integration Services Project”. Name the project SalesETL. Set the TargetServerVersion in project properties to match the SQL Server version.

Step 2: Build the control flow

Open Package.dtsx. On the Control Flow tab, drag in an Execute SQL Task. Double-click it and configure it to truncate the staging table:

TRUNCATE TABLE dbo.Customers_Stage;

Drag in a Data Flow Task below it. Connect them with a precedence constraint (green arrow — Success).

Step 3: Build the data flow

Double-click the Data Flow Task to open the Data Flow tab. Add an OLE DB Source connected to the source database. Configure it to read from dbo.Customers. Add a Derived Column transformation. Create a new column FullName:

[FirstName] + " " + [LastName]

Add an OLE DB Destination connected to the staging table. Map columns. Create the staging table if needed:

CREATE TABLE dbo.Customers_Stage (
    CustomerID   INT,
    FirstName    NVARCHAR(50),
    LastName     NVARCHAR(50),
    FullName     NVARCHAR(100)
);

Step 4: Add an OnError event handler

Click the Event Handlers tab. In the Executable dropdown, select Package. In the Event Handler dropdown, select OnError. Add a Send Mail Task. Configure it with the SMTP connection manager and the DBA team email address. This fires and sends an email any time the package fails.

Step 5: Deploy to SSISDB

Right-click the project in Solution Explorer → Deploy. In the Integration Services Deployment Wizard, select the SSISDB instance and a target folder. Complete the wizard. The project deploys as an .ispac file.

Step 6: Create an environment and bind parameters

In SSMS, expand SSISDB → the folder → Environments. Right-click → Create Environment. Name it Production. Add a variable SourceConnString and set its value to the production connection string. Right-click the deployed project → Configure → References tab → add a reference to the Production environment. Map project parameters to environment variables.

Step 7: Execute and monitor

-- Execute via T-SQL with environment reference
DECLARE @execution_id BIGINT;

EXEC catalog.create_execution
    @folder_name       = N'ETL',
    @project_name      = N'SalesETL',
    @package_name      = N'Package.dtsx',
    @reference_id      = (SELECT reference_id FROM catalog.environment_references
                          WHERE environment_name = 'Production'),
    @execution_id      = @execution_id OUTPUT;

EXEC catalog.start_execution @execution_id = @execution_id;

-- Monitor result
SELECT execution_id, status, start_time, end_time
FROM catalog.executions
WHERE execution_id = @execution_id;

Workshop 2: Configure SSISDB with Always On Availability Groups

Prerequisites

SQL Server Enterprise on at least two nodes. An Always On AG already configured with a listener. SSISDB created on the primary node. Master key backed up.

Step 1: Enable CLR on all nodes

EXEC sp_configure 'clr enabled', 1;
RECONFIGURE;
GO

Step 2: Add SSISDB to the AG

ALTER AVAILABILITY GROUP [ProductionAG] ADD DATABASE SSISDB;
GO

Step 3: Restore the master key on each secondary

Copy the master key backup file to each secondary node. On each secondary replica, run:

USE SSISDB;
GO
RESTORE MASTER KEY
FROM FILE = 'C:\SSISKeys\SSISDBMasterKey.key'
DECRYPTION BY PASSWORD = 'YourKeyBackupPassword'
ENCRYPTION BY PASSWORD = 'SecondaryNodeKeyPassword'
FORCE;
GO

ALTER MASTER KEY ADD ENCRYPTION BY SERVICE MASTER KEY;
GO

Step 4: Create a SQL Agent job using the listener

In SSMS, connect to the AG listener. Create a SQL Agent job with an Integration Services Package step. Set the server name on the step to the AG listener name. This ensures the job continues to work after any failover.

Step 5: Test failover

In SSMS, right-click the AG and select Failover. After failover completes, connect to the listener (which now points to the new primary). Execute the SSIS package via the Agent job. Confirm execution succeeds and history appears in SSISDB on the new primary. Fail back and confirm continuity.

Step 6: Verify SSISDB health after failover

-- Confirm SSISDB is on the current primary and synchronized
SELECT
    ar.replica_server_name,
    drs.synchronization_state_desc,
    drs.synchronization_health_desc,
    drs.is_primary_replica
FROM sys.dm_hadr_database_replica_states  drs
JOIN sys.availability_replicas             ar  ON drs.replica_id = ar.replica_id
WHERE DB_NAME(drs.database_id) = 'SSISDB';
GO

The technical information in this article was verified against Microsoft documentation at the time of publication. SQL Server features, cloud service capabilities, licensing terms, and configuration requirements can change between versions and cumulative updates. Always validate implementation details against current Microsoft Learn documentation before deploying to production. References in this article link directly to the authoritative Microsoft sources.


Discover more from SQLYARD

Subscribe to get the latest posts sent to your email.

Leave a Reply

Discover more from SQLYARD

Subscribe now to keep reading and get access to the full archive.

Continue reading