Skip to main content

Precedence Constraints in Biml

Why Constraint Control Matters

Biml controls SSIS task execution order at two levels. The package level sets a default through the 'ConstraintMode' attribute, which is mandatory. Individual tasks can override that default by declaring a 'PrecedenceConstraints' element with explicit input paths.

Linear Constraint Mode

Setting 'ConstraintMode' to Linear creates a precedence constraint between tasks in the order they appear in script:

<Package Name="PrecedenceConstraints" ConstraintMode="Linear">
<Tasks>
<ExecuteSQL Name="Step1" ConnectionName="DB_Src">
<DirectInput>Select 1</DirectInput>
</ExecuteSQL>
<ExecuteSQL Name="Step2" ConnectionName="DB_Src">
<DirectInput>Select 2</DirectInput>
</ExecuteSQL>
<ExecuteSQL Name="Step3" ConnectionName="DB_Src">
<DirectInput>Select 3</DirectInput>
</ExecuteSQL>
</Tasks>
</Package>

Tasks chain in the declared order, each one waiting for the previous one to succeed.

Parallel Constraint Mode

Setting 'ConstraintMode' to Parallel adds the same tasks to the control flow without any precedence between them. All three start in parallel:

<Package Name="PrecedenceConstraints" ConstraintMode="Parallel">
<Tasks>
<ExecuteSQL Name="Step1" ConnectionName="DB_Src">
<DirectInput>Select 1</DirectInput>
</ExecuteSQL>
<ExecuteSQL Name="Step2" ConnectionName="DB_Src">
<DirectInput>Select 2</DirectInput>
</ExecuteSQL>
<ExecuteSQL Name="Step3" ConnectionName="DB_Src">
<DirectInput>Select 3</DirectInput>
</ExecuteSQL>
</Tasks>
</Package>

Overriding the Default Per Task

To express more complex graphs, set 'PrecedenceConstraints' on the downstream task. The 'OutputPathName' value is the upstream task name suffixed with '.Output'. Suppose the goal is for Step1 to chain into Step2, with Step3 running in parallel from Step1:

<ExecuteSQL Name="Step3" ConnectionName="DB_Src">
<DirectInput>Select 3</DirectInput>
<PrecedenceConstraints>
<Inputs>
<Input OutputPathName="Step1.Output" />
</Inputs>
</PrecedenceConstraints>
</ExecuteSQL>

Combined with a Linear package mode, this produces the chain Step1 then Step2, with Step3 fed only by Step1.

Linear Mode Still Applies When Inputs Are Empty

Adding a fourth task to a Linear package without an explicit constraint causes the package default to apply to that task. If Step3 should depend on both Step1 and Step4, declaring Step4 last and listing both inputs on Step3 looks correct:

<ExecuteSQL Name="Step1" />
<ExecuteSQL Name="Step2" />
<ExecuteSQL Name="Step3">
<PrecedenceConstraints>
<Inputs>
<Input OutputPathName="Step1.Output" />
<Input OutputPathName="Step4.Output" />
</Inputs>
</PrecedenceConstraints>
</ExecuteSQL>
<ExecuteSQL Name="Step4" />

The trap is that Step4 has no explicit constraints, so the Linear package default chains it to Step3, which already depends on Step4. The result is a circular dependency that can crash the designer.

The fix is to declare an empty 'Inputs' element on Step4 so the Linear default does not apply:

<ExecuteSQL Name="Step4" ConnectionName="DB_Src">
<DirectInput>Select 4</DirectInput>
<PrecedenceConstraints>
<Inputs />
</PrecedenceConstraints>
</ExecuteSQL>

Tasks can now appear in any order, but every task that does not match the Linear default needs an explicit declaration.

Logical Conditions for Multiple Inputs

When a task has more than one input, the 'LogicalType' attribute on 'PrecedenceConstraints' decides whether all inputs must complete before the task fires (And, the default) or only one of them (Or):

<ExecuteSQL Name="Step3" ConnectionName="DB_Src">
<DirectInput>Select 3</DirectInput>
<PrecedenceConstraints LogicalType="Or">
<Inputs>
<Input OutputPathName="Step1.Output" />
<Input OutputPathName="Step4.Output" />
</Inputs>
</PrecedenceConstraints>
</ExecuteSQL>

Failure-Based Branches

For error handling, an individual input can require a failure rather than a success outcome through 'EvaluationValue'. The example below fires Step3 when Step1 succeeds and Step4 fails:

<ExecuteSQL Name="Step3" ConnectionName="DB_Src">
<DirectInput>Select 3</DirectInput>
<PrecedenceConstraints>
<Inputs>
<Input OutputPathName="Step1.Output" />
<Input OutputPathName="Step4.Output" EvaluationValue="Failure" />
</Inputs>
</PrecedenceConstraints>
</ExecuteSQL>

Summary

Default constraint behavior is set on the package and applies whenever a task does not declare its own. Per-task overrides cover any layout but require an empty 'Inputs' element to opt out of a Linear default. 'LogicalType' and 'EvaluationValue' cover the remaining branching cases.