这是我参与11月更文挑战的第13天,活动详情查看:2021最后一次更文挑战
翻译参考
本文主要参考翻译自 The Stairway to Integration Services
系列文章的 Basic SSIS Workflow Management – Level 6 of the Stairway to Integration Services,目的在于对 SSIS 有一个全面清晰的认识,所有内容在原文的基础上进行实操,由于版本差异、个人疑问等多种原因,未采用完全翻译的原则,同时也会对文中内容进行适当修改,希望最终可以更有利于学习和了解 SSIS,
感谢支持!
基本的 SSIS 工作流管理
介绍
之前的部分,重点介绍了实现增量加载(loading
)数据。本篇我们将关注在 SSIS 控制流(SQL Server Integration Services Control Flow
)中使用 “优先约束”(Precedence Constraints
) 管理工作流。
SSIS控制流包含 任务、容器 和 优先约束(Tasks, Containers, and Precedence Constraints
)。任务 和 容器 在SSIS控制流中是可执行的项目;优先级约束 管理何时或是否执行 任务 或 容器。
添加一个包(Package)
开始控制流之前,打开存在的 “FirstSSIS” 项目,右键在解决方案管理器中的 “SSIS包”(SSIS Packages
) 虚拟文件夹,点击 “新建SSIS包”(New SSIS Package
)
当点击”新建包”后,一个新的名为 “Package1.dtsx” 包被创建并显示。右键 Package1.dtsx
点击 “重命名”,该包会进入 “重命名模式”(rename mode
),重命名为 Precedence.dtsx
:
添加一个脚本任务Script Task
脚本任务
Script Task
,通过 C# 或 VB.Net 语言实现编程和更强大功能的扩展!
如在第一个demo中见到的,没有优先约束也是有效的SSIS包。
首先,从 “控制流”工具箱 向 “控制流” 添加脚本任务。单击工具箱中的 脚本任务(Script Task
),然后将其拖到 “控制流” 中。
脚本任务可以说是 SQL Server Integration Services 中功能最强大的 SSIS任务。你可以使用它来创建其他SSIS任务中包含的许多功能。还可以使用脚本任务将新功能添加到SSIS控制流中。
右键 “脚本任务” 点击 “编辑”,打开脚本任务编辑器(Script task Editor
)
下面将介绍脚本任务功能的基础部分。
首先,你可能想检查 “ScriptLanguage” 属性,此处可以选择在每个脚本任务中使用 Visual Basic
或 C#
作为你的编程语言。
可以通过在 SSDT 的编辑器中,选择 “工具” → “选项” → “商业智能设计器” → “Integration Services设计器”,在 脚本-语言 下拉菜单中更改 “脚本”任务的默认语言。
点击常规页(General page
),改变Name属性为”Script Task 1”。
返回脚本页(Script page
)中。点击 “ReadOnlyVariables” 属性,点击右侧省略号打开可用变量(available Variables
)列表。选择如下显示的 “System::TaskName” 变量。点击“确定”,关闭该选项窗口。
此处我们需要在当前屏幕配置脚本。点击 “编辑脚本”(Edit Script
) 按钮。
关于打开 “编辑脚本” 报错的问题
如下,打开时报错”未能加载文件或程序集”
原本以为这个报错是和没有安装完整的”Visual Studio”有关,但是后来测试在其他没有 “完整”VS 的电脑上却没有这个问题。
系统和SQL Server版本、配置都是相同的。进行系统更新和sfc检查等,都没解决这个报错。
在打开的脚本代码编辑中,滚动找到 Main 函数并添加如下代码:
1 | cs复制代码var sTaskName = Dts.Variables["TaskName"].Value.ToString(); |
显示如下:
该代码实现的是:第一句创建一个名为 sTaskName
的string类型的变量(C#),并将脚本任务的 ReadOnlyVariables
属性中添加的 System::TaskName
的值赋值给它。通过访问 Dts
命名空间的变量集 获取 SSIS变量值(即Dts.Variables
部分)。Variables集合的键为SSIS变量的名称(此处获取 TaskName
)。
然后获取属性值,它是一个对象,需要获取其String类型值。
这样就实现了从一个 SSIS变量读取值到”脚本”(Script Task
)变量(在C#中)
在SSIS中,变量具有作用域(
scope
)并属于命名空间。作用域是SSIS变量所属的容器,每一个SSIS变量都与一个命名空间关联。默认有两个命名空间 ——System
和User
。TaskName
属于系统命名空间,用<NameSpace>::<VariableName>
表示。变量名在一个给定的作用域和命名空间内是唯一的。也就是,
System
命名空间下TaskName
变量,然后,也可以在User
命名空间下,添加同样叫TaskName
的变量(此处原文有问题,写的是不同命名空间下变量名不可以重复,因为不同命名空间下,都是可以变量名存在相同的[命名空间进行了限定],同一个命名空间下变量名不可以重复,不同命名空间下变量名互不影响)
下一句显示一个包含任务名(来自 sTaskName
变量)的消息提示框。
点击右上角的”X”,关闭脚本任务代码编辑器(Script Task Code Editor
)。脚本会自动保存。在 脚本任务编辑器(Script Task Editor
) 中点击确定(OK),完成脚本任务配置。
下面进行测试。点击 “启动调试” 或 F5 运行SSIS包。将会看到如下消息框:
停止调试运行。
添加第二个脚本任务
添加 TaskName 变量似乎需要很多额外的工作。不过此处有更好的方法。右键点击 “Script Task 1”,点击复制(“Copy”),然后 右键 点击 除”Script Task 1”之外 的控制流的空白部分,点击粘贴(“Paste”)。一个新脚本任务添加到控制流中。名字为Script Task 1 1
。将其重命名为”Script Task 2”
重新执行SSIS包,将会显示两次消息框。
使用优先约束(Cases 0 和 1)
前面的示例是一个”用例”(use case
)例子。该use case
演示了没有优先约束的情况。可以将此称为 “用例0”(Use Case 0
)。
对于当前正在操作的”用例1”(Use Case 1
),我们在 Script Task 1
和 Script Task 2
之间添加优先约束。
点击Script Task 1
,Script Task 1
底部扩展出来的绿色箭头就是一个优先约束(Precedence Constraint
)。点击并拖拽优先约束到Script Task 2
。
运行SSIS包,Script Task 1
会首先执行,然后再执行 Script Task 2
。
另外需要注意的一点是 优先约束 的类型是 OnSuccess
,即优先级”评估”(evaluate)之前,必须先完成并成功执行上一个任务 —— Script Task 1
。
停止当前的调试运行。
这里的语义(
semantics
)很重要。优先级约束始于Script Task 1
,终止于Script Task 2
。始发任务连接到优先级约束起点,该起点具有“半气泡”(half-bubble
)特性,在该起点连接到始发任务。端点在连接到 “终止任务”(terminating task
) 的地方有一个箭头。优先约束评估(
Precedence constraints evaluate
)。它们测试一个或多个条件,如果条件为真,则约束条件允许 “终止任务” 开始执行。
“单线程”(Single-Threading)
“单线程”描述为一次做一件事情的一种方式。在 SSIS 控制流中使用一个优先约束是一种实现单线程的方式。
使用优先约束是在控制流中完成确定性工作流(deterministic workflow
)的唯一方法。
SSIS控制流程中是否可以使用不确定的工作流(non-deterministic workflow
)?答案是”是的”。右击连接 Script Task 1
和 Script Task 2
的优先约束,然后点击”删除”。点击工作流空白处,按下 F4
键(或者直接在右侧找到”属性”),查看包属性。
MaxConcurrentExecutables
属性控制SSIS控制流中可以同时执行多少个可执行文件,默认值为-1
。SSIS允许的并发执行的默认数量 等于 检测到的CUP核心数量加2。例如:如果你有一个4核的服务器,SSIS将会允许6个并发执行。
设置 MaxConcurrentExecutables
属性为1。
重新执行SSIS包。现在一次仅仅执行一个脚本任务。这个顺序是非确定的(non-deterministic
)并因此不可预测的(unpredictable
)。
停止调试,重设 MaxConcurrentExecutables
属性为-1
,并保存。
总结
本篇中,我们添加一个新的SSIS包到解决方案中,构建我们第一个脚本任务,并通过 “OnSuccess” 优先约束连接它们。测试了从 SSIS脚本任务 内部读取SSIS变量值,查看和设置了 SSIS包 的 MaxConcurrentExecutables
属性。
本文转载自: 掘金