{"id":617,"date":"2009-07-07T00:00:00","date_gmt":"2009-07-07T00:00:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/working-with-precedence-constraints-in-sql-server-integration-services\/"},"modified":"2021-06-03T16:45:29","modified_gmt":"2021-06-03T16:45:29","slug":"working-with-precedence-constraints-in-sql-server-integration-services","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/databases\/sql-server\/bi-sql-server\/working-with-precedence-constraints-in-sql-server-integration-services\/","title":{"rendered":"Working with Precedence Constraints in SQL Server Integration Services"},"content":{"rendered":"<div id=\"PRETTY\">\n<p>The control flow in a SQL Server Integration Services (SSIS) package defines the workflow for that package. Not only does the control flow determine the order in which executables (tasks and containers) will run, the control flow also determines under what conditions they&#8217;re executed. In other words, certain executables will run only when a set of defined conditions are met.<\/p>\n<p>You configure the workflow by using <i>precedence constraints<\/i>. Precedence constraints link the individual executables together and determine how the workflow moves from one executable to the next. Figure 1 shows the control flow for the <b>PrecedenceConstraints.dtsx<\/b> package. The precedence constraints are the green and red arrows (both solid and dotted) that connect the tasks and container to each other. (There can also be blue arrow, as you&#8217;ll learn later in the article.)<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/750-ST_PrecConstraints01.jpg\" width=\"640\" height=\"360\" alt=\"750-ST_PrecConstraints01.jpg\" \/><\/p>\n<p class=\"caption\">Figure 1: Control Flow in the PrecedenceConstraints.dtsx SSIS package<\/p>\n<p>As you would expect, the arrows define the direction of the workflow as it moves from one executable to the next. For example, after the first <b>Execute SQL<\/b> task runs, the precedence constraints direct the workflow to the next <b>Execute SQL<\/b> task and the <b>Sequence<\/b> container. One or both of these executables will run, depending on how the precedence constraints have been configured.<\/p>\n<p>When a precedence constraint connects executables, the originating executable (the first to run) is referred to as the <i>precedence executable.<\/i> Multiple precedence constraints can originate from the precedence executable. In the first <b>Execute SQL<\/b> task in Figure 1, two precedence constraints originate from that precedence executable.<\/p>\n<p>The task or container that is on the downstream end of the precedence constraint is referred to as the <i>constrained executable<\/i>. The constrained executable will run only if the conditions defined on the precedence constraint are met. If the conditions are not met, the constrained executable will not run. As a result, by configuring the precedence constraints, you can create complex workflows, while minimizing the need to configure duplicate tasks and containers.<\/p>\n<p>Note that I created the PrecedenceConstraints.dtsx package in SSIS 2005. However, I upgraded the package to SSIS 2008 to ensure that precedence constraints are implemented the same in both versions. You can download the SSIS 2005 version of the <a href=\"http:\/\/www.simple-talk.com\/content\/file.ashx?file=2097\">PrecedenceConstraints.dtsx<\/a>&#160;package at the bottom of the article. <\/p>\n<p>If you want to run the PrecedenceConstraints.dtsx package, you should first run the following Transact-SQL code against the AdventureWorks sample database:<\/p>\n<pre class=\"theme:ssms2012 lang:tsql\">IF EXISTS(\r\n&#160; SELECT table_name FROM information_schema.tables \r\n&#160; WHERE table_name = 'Employees')\r\nDROP TABLE Employees\r\nGO\r\nCREATE TABLE Employees \r\n(\r\n&#160; EmployeeID INT PRIMARY KEY,\r\n&#160; FirstName NVARCHAR(50) NOT NULL,\r\n&#160; LastName NVARCHAR(50) NOT NULL,\r\n&#160; Jobtitle NVARCHAR(50) NOT NULL\r\n)\r\nGO\r\nIF EXISTS(\r\n&#160; SELECT table_name FROM information_schema.tables \r\n&#160; WHERE table_name = 'EmployeeLog')\r\nDROP TABLE EmployeeLog\r\nGO\r\nCREATE TABLE EmployeeLog \r\n(\r\n&#160; LogID INT IDENTITY PRIMARY KEY,\r\n&#160; LogFile VARCHAR(50) NULL,\r\n&#160; LogDateTime DATETIME NOT NULL DEFAULT GETDATE()\r\n)\r\n<\/pre>\n<p>The code creates the Employees table and EmployeeLog table, both of which are necessary to run the PrecedenceConstraints.dtsx package. The package itself archives employee data, logs information about the package execution, truncates the Employees table if necessary, retrieves data through the HumanResources.vEmployee view, and loads it into the Employees table. The package uses different types of precedence constraints to control the workflow for these various operations. We&#8217;ll look at the workflow and precedence constraints in closer detail as we work through the article.<\/p>\n<h1>Defining Workflow by Success or Failure<\/h1>\n<p>By default, when a precedence constraint connects two executables, the constrained executable will run after the precedence executable successfully runs. However, if the precedence executable fails, that part of the workflow is interrupted, and the constrained executable does not run. You can override this behavior by setting the <b>Value<\/b> property on the precedence constraint. The property supports three options:<\/p>\n<ul>\n<li><b>Success:<\/b> The precedence executable must run successfully for the constrained executable to run. This is the default value. The precedence constraint is set to green when the <b>Success<\/b> option is selected.  <\/li>\n<li><b>Failure:<\/b> The precedence executable must fail for the constrained executable to run. The precedence constraint is set to red when the <b>Failure<\/b> option is selected.  <\/li>\n<li><b>Completion:<\/b> The constrained executable will run after the precedence executable runs, whether the precedence executable runs successfully or whether it fails. The precedence constraint is set to blue when the <b>Completion<\/b> option is selected. <\/li>\n<\/ul>\n<p>If you refer back to Figure 1, you&#8217;ll see that the two precedence constraints originate from the <b>Data Flow<\/b> task, one green and one red. If the <b>Data Flow<\/b> task runs successfully, the first <b>Send Mail<\/b> task will run because the green precedence constraint connects to that <b>Send Mail <\/b>task. Because the <b>Value<\/b> property of the precedence constraint is set to <b>Success<\/b>, the precedence constraint will evaluate to true and the workflow will continue along that path.<\/p>\n<p>However, if the <b>Data Flow<\/b> task fails, the red precedence constraint will evaluate to true because its <b>Value<\/b> property is set to <b>Failure<\/b>. As a result, the second <b>Send Mail<\/b> task will run. This way, you can configure each <b>Send Mail<\/b> task differently so that you&#8217;re sending a unique email based on whether the <b>Data Flow<\/b> task succeeds or fails.<\/p>\n<div class=\"note\">\n<p class=\"note\"><b>Note<\/b>: The two <b>Send Mail<\/b> tasks and the <b>SMTP<\/b> connection manager are included here for demonstration purposes only. If you want to tests these tasks, you will need to point the connection manager to an actual SMTP server and configure the tasks appropriately. Otherwise, you should disable the tasks or they will fail when you try to run the package. (Even if they do fail, however, the package will still run and load the data as expected.)<\/p>\n<\/div>\n<h1>Defining Workflow by Expressions<\/h1>\n<p>Although defining workflow by execution outcome (success, failure, or completion) can be useful, the workflow logic is still limited to that outcome. However, you can further refine your workflow by adding expressions to the precedence constraints. Any expression you add must be a valid SSIS expression and must evaluate to true or false.<\/p>\n<p>To add an expression, double-click the precedence constraint to open the <b>Precedence Constraint Editor<\/b> dialog box, as shown in Figure 2. (The editor shown in this figure is the one for the precedence constraint that connects the first and second <b>Execute SQL <\/b>tasks.)<\/p>\n<p class=\"ILLUSTRATION\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.red-gate.com\/simple-talk\/wp-content\/uploads\/imported\/750-ST_PrecConstraints02.jpg\" width=\"496\" height=\"361\" alt=\"750-ST_PrecConstraints02.jpg\" \/><\/p>\n<p class=\"caption\">Figure 2: Defining an expression in the Precedence Constraint Editor dialog box<\/p>\n<p>When adding an expression to a precedence constraint, the first step you must take is to select one of the following options from the <b>Evaluation operation<\/b> drop-down list:<\/p>\n<ul>\n<li><b>Constraint:<\/b> The precedence constraint is evaluated solely on the option selected in the <b>Value<\/b> property. For example, if you select <b>Constraint <\/b>as the<b> Evaluation operation<\/b> option and select <b>Success<\/b> as the <b>Value<\/b> option (the default settings for both properties), the precedence constraint will evaluate to true only if the precedence executable runs successfully. When the precedence constraint evaluates to true, the workflow continues and the constrained executable runs. (When the <b>Constraint<\/b> option is selected, the <b>Expression<\/b> property is greyed out.)  <\/li>\n<li><b>Expression:<\/b> The precedence constraint is evaluated based on the expression defined in the <b>Expression<\/b> text box. If the expression evaluates to true, the workflow continues and the constrained executable runs. If the expression evaluates to false, the constrained executable does not run. (When the <b>Expression<\/b> option is selected, the <b>Value<\/b> property is greyed out.)  <\/li>\n<li><b>Expression and Constraint:<\/b> The precedence constraint is evaluated based on both the <b>Value<\/b> property and the expression. Both must evaluate to true for the constrained executable to run. For example, in the <b>PrecedenceConstraints.dtsx <\/b>package, the first <b>Execute SQL <\/b>task must run successfully and the expression must evaluate to true for the precedence constraint to evaluate to true and the constrained executable to run.  <\/li>\n<li><b>Expression or Constraint:<\/b> The precedence constraint is evaluated based on either the <b>Value<\/b> property or the expression. At least one of these properties must evaluate to true for the constrained executable to run. <\/li>\n<\/ul>\n<p>After you&#8217;ve selected an option from the <b>Evaluation operation<\/b> list (and set the <b>Value<\/b> property, if appropriate), you&#8217;re next step is to define the expression. The expression I&#8217;ve used in this case (shown in Figure 2), determines whether the @EmployeeCount property equals 0 (<code>@EmployeeCount == 0).<\/code> <\/p>\n<p>To better understand how this works, let&#8217;s take a quick look at the first <b>Execute SQL<\/b> task. The task runs the following SELECT statement to retrieve the number of rows in the Employees table:<\/p>\n<pre>SELECT COUNT(*) FROM Employees\r\n<\/pre>\n<p>The task then assigns the statement&#8217;s results (a scalar integer value) to the @EmployeeCount variable, which I defined when I set up the SSIS package.<\/p>\n<p>The precedence constraint expression then uses the variable value to determine whether it equals 0. If it does, the expression evaluates to true. If not, it evaluates to false. Because the <b>Value<\/b> property precedence constraint is also set to <b>Success<\/b>, the first <b>Execute SQL<\/b> task must run successfully and the expression must evaluate to true for the precedence constraint as a whole to evaluate to true. If it does, the second <b>Execute SQL<\/b> task runs.<\/p>\n<p>The precedence constraint that connects the first <b>Execute SQL<\/b> task to the <b>Sequence<\/b> container uses similar logic. However, the expression itself is slightly different:<\/p>\n<pre>@EmployeeCount &gt; 0\r\n<\/pre>\n<p>In this case, the <code>@EmployeeCount<\/code> value must be greater than 0 for the expression to evaluate to true. If it does evaluate to true and the first <b>Execute SQL <\/b>task runs successfully, the <b>Sequence<\/b> container and the tasks within it will run. <\/p>\n<p>Notice that the expressions in the two precedence constraints that originate from the first <b>Execute SQL<\/b> task are mutually exclusive. That is, only one of the two expressions can ever evaluate to true during a specific execution. That does not mean that you cannot have multiple precedence constraints with expressions that all evaluate to true during a single execution, but it does mean that you want to use caution when implementing expression to insure that they reflect exactly the logic you&#8217;re trying to implement in your workflow. In this case, I want to ensure that only one precedence constraint evaluates to true during a single execution.<\/p>\n<div class=\"note\">\n<p class=\"note\"><b>Note<\/b>: SSIS expressions are an entity unto themselves and unique to SSIS packages and their components. It is beyond the scope of this article to get into the details of expressions, but it is important to get them right. Be sure to refer to the topic &#8220;Integration Services Expression Reference&#8221; in SQL Server Books Online if you have any questions about SSIS expressions.<\/p>\n<\/div>\n<h1>Defining Workflow by Logical AND or Logical OR<\/h1>\n<p>Two other important configuration options in a precedence constraint are the <b>Logical OR<\/b> and <b>Logical AND<\/b> settings. These settings apply only to constrained executables and only if those executables have more than one precedence constraint directed to it. For example, the <b>Data Flow<\/b> task in the <b>PrecedenceConstraints.dtsx<\/b> package (shown in Figure 1) has two precedence constraints pointing to it: one from the second <b>Execute SQL<\/b> task and one from the <b>Sequence<\/b> container.<\/p>\n<p>If you refer back to Figure 2, you&#8217;ll find the following two options at the bottom of the <b>Precedence Constraint Editor<\/b> dialog box:<\/p>\n<ul>\n<li><b>Logical AND:<\/b> All precedence constraints that point to the constrained executable must evaluate to true in order for that executable to run. This is the default option. If it is selected, the arrow is solid.  <\/li>\n<li><b>Logical OR:<\/b> Only one precedence constraint that points to the constrained executable must evaluate to true in order for that executable to run. If this option is selected, the arrow is dotted. <\/li>\n<\/ul>\n<p>In the case of the precedence constraints that point to the <b>Data Flow<\/b> task, it is the second option that is selected, as indicated by the dotted lines. As a result, the workflow can originate from either the second <b>Execute SQL<\/b> task or from the <b>Sequence <\/b>container, and only one of the precedence executables has to run successfully.<\/p>\n<p>The <b>Logical OR<\/b> and the <b>Logical AND<\/b> options let you define multiple execution paths, yet share those elements that are common to each path, such as the <b>Data Flow<\/b> task in the <b>PrecedenceConstraints.dtsx<\/b> package. The logical AND\/OR settings, along with the <b>Value<\/b> property and the use of expressions, provide you with the options necessary to define intricate workflows while minimizing duplicate efforts. <\/p>\n<p>Despite its simplicity, the <b>PrecedenceConstraints.dtsx<\/b> package described in this article demonstrates all these elements and should provide you with the foundation you need to use precedence constraints to their fullest. However, you can find additional information about precedence constraints in the topic <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms141221.aspx\">&#8220;Setting Precedence Constraints on Tasks and Containers&#8221;<\/a> in SQL Server Books Online.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In SSIS, tasks are linked by precedence constraints.  A task will only execute if  the condition that is set by the precedence constraint\u00a0preceding the task is met. By using these constraints, it is possible to ensure different execution paths depending on the success or failure of other tasks. This means that you can use  tasks with precedence constraints to determine the workflow of an SSIS package. We challenged Rob Sheldon to provide a straightforward practical example of how to do it. &hellip;<\/p>\n","protected":false},"author":221841,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[143528],"tags":[4991,4150,4151,4306],"coauthors":[6779],"class_list":["post-617","post","type-post","status-publish","format-standard","hentry","category-bi-sql-server","tag-example-tutorial-ssis-beginning","tag-sql","tag-sql-server","tag-ssis"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/617","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/221841"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=617"}],"version-history":[{"count":6,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/617\/revisions"}],"predecessor-version":[{"id":91237,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/617\/revisions\/91237"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=617"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=617"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=617"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}