开篇介绍

Execute SQL Task 这个控件在微软BI ETL 项目中使用的频率还是非常高的,也是大部分入门 SSIS 初学者最早接触到的几个控制流控件。
我们通常使用 Execute SQL Task 的场景包含但不止于以下几类:
  1. 在从源端加载数据到 Staging 表之前使用 Execute SQL Task 执行一些 Truncate 操作。
  2. 执行一些 Log 的插入,更新操作。
  3. ETL 过程中的 Merge 语句操作。
  4. XML 的输出处理。
关于如何使用 Execute SQL Task 就不在本文讲解了,包括参数传递 Input,存储过程返回值 Output,包括 Return Value ,还有 SQL Source Type 等不同方式以及 OLD DB,ADO.NET 区别等基础概念文本也不会涉及到。
 
本文要讲解的内容是针对 ResultSet 的几种类型:None, Single row, Full result set, XML。其中 None 不用讲解,关于 XML 的内容大家可以参考我的另一篇文章 两种将 SQL Server 数据库数据输出成 XML 文件的方法,因此在这里只讲解 Single Row 和 Full Result Set 的处理方法。

Single Row

首先,Single Row 指的就是在 Execute SQL Task 中返回的就是一个单行的记录,允许多列。
通常在 Execute SQL Task 中使用 Single Row 的时候是为了在控制流中控制流程的流转,满足一定的条件走一个分支流程,不满足则走另外一个流程。
比如,在包执行之初查询数据库检查一下包的某些状态,或者数据的某些状态,只有在满足达到一定条件下才能执行剩下的流程,否则则不执行包或者报错。这类设计在各种不同的BI项目中可能都存在,那么其原型就是利用 Execute SQL Task 中的 Single Row返回的值来控制流程。
有以下几个步骤:
  1. SQL Statement 中的语句返回单行记录,可以多列。
  2. 需要在包中实现定义变量用来接收 Single Row 的某列上的值。
  3. 使用 Precedence Constraint 和变量来控制流程。

Single Row 案例

一条简单的查询语句返回一个单行双列的记录。
设置好连接并放好SQL语句,选择 Single Row。
添加三个变量
  1. EXISTING_COUNT - 用来接收查询中的返回的COUNT数。
  2. MAX_DATE - 用来接收查询中返回的最大时间。
  3. TEST_DATE - 测试时间,比如说 2014-01-01。

0 表示 Single Row 中的第一列,1 表示 Single Row 中的第二列。
下面放两个空的 Data Flow Task 并关联到 Execute SQL Task,点击连接线设置条件控制。
DFT_TEST_AFTER_MAX 上的连接线条件判断为:DATEDIFF( "dd", (DT_DBDATE) (@[User::TEST_DATE]) , (DT_DBDATE) (@[User::MAX_DATE])) >=0
DFT_TEST_BEFORE_MAX上的判断表达式为:DATEDIFF( "dd", (DT_DBDATE) (@[User::TEST_DATE]) , (DT_DBDATE) (@[User::MAX_DATE])) <0
左右两个数据流下各加入一个 Script Task 显示一下这几个变量的值,代码如下:
public void Main()
{
// TODO: Add your code here
//User::EXISTING_COUNT,User::MAX_DATE,User::TEST_DATE
string existing_count = Dts.Variables["User::EXISTING_COUNT"].Value.ToString();
string max_date = Dts.Variables["User::MAX_DATE"].Value.ToString();
string test_date = Dts.Variables["User::TEST_DATE"].Value.ToString(); MessageBox.Show("Existing Count - " + existing_count + ", test date - " + test_date + ", max date - " + max_date);
Dts.TaskResult = (int)ScriptResults.Success;
}

保存并执行包,流程走了右边,因为 MAX DATE 要比 TEST DATE 大。

修改 TEST_DATE,那么 TEST DATE 要比 MAX DATE 大。
这就是 Execute SQL Task 中 Single Row 的使用方法。

FULL Result Set

通常在 Execute SQL Task 中使用到 FULL Result Set 就一定会结合 Foreach Loop 来使用,所适用的场景是循环便利查询结果集中的每一行数据,将每一行的数据其中某几列取出来放入到变量中,然后同样在 Foreach Loop 中的其它控制流控件使用这些变量做一些操作。

疑问

像这种遍历为什么不放到数据库中直接遍历不是更好吗?问题就在于,有时操作的对象并不仅仅是数据库中的表对象,而是涉及到不同的文件处理,这时就需要使用这种方式了。比如,我的目标数据源中有几百个文件,且文件的命名包括产品的名称,现在表中有产品名称的记录。需要循环遍历表中的产品,并对比哪些文件命名包含有这些产品名称,包含产品名称的文件则抽取数据,不包含产品名称的文件则移到其它目录。
下面使用这个查询作为一个示例结果集 -
 
使用 FULL RESULT SET  
定义如下几个变量 - ORDER_SET 用来保存 Execute SQL Task 查询中的结果集,其它变量用来在循环每一行的时候保存每一列的值。注意:返回的结果集要使用 OBJECT 类型的变量来保存,这个 OBJECT 类型在内部以集合的形式存在并保存整个查询结果集。
EXECUTE SQL TASK 的 Mapping。

Foreach 下的设置

我们可以通过 Foreach 的方式循环遍历这个返回的集合。添加一个 Foreach 控件,并设置遍历方式 - Foreach ADO Enumerator 和要遍历的集合对象。
遍历这个集合的时候,每次返回一行,这一行也是一个集合,通过设置索引0,1,2 将这个集合的元素赋值给各个变量。
在 Foreach 控件中添加一个 Script Task 用来显示每一行中各列的内容。
Script 中的脚本代码如下:
public void Main()
{
// TODO: Add your code here
//User::PRODUCT_ID,User::SALES_ORDER_DETAIL_ID,User::UNIT_PRICE
string detailID = Dts.Variables["User::SALES_ORDER_DETAIL_ID"].Value.ToString();
string productID = Dts.Variables["User::PRODUCT_ID"].Value.ToString();
string unitPrice = Dts.Variables["User::UNIT_PRICE"].Value.ToString(); MessageBox.Show("Detail ID - " + detailID+", Product ID - "+productID +", Unite Price - "+ unitPrice);
Dts.TaskResult = (int)ScriptResults.Success;
}

保存并执行包,第一次循环的结果是失败的,但是可以看出来我们的结果集返回是没有问题的。

出错的原因如下:
Error: The type of the value (String) being assigned to variable "User::SALES_ORDER_DETAIL_ID" differs from the current variable type (Int32). Variables may not change type during execution. Variable types are strict, except for variables of type Object.
Error: The type of the value (String) being assigned to variable "User::PRODUCT_ID" differs from the current variable type (Int32). Variables may not change type during execution. Variable types are strict, except for variables of type Object.
Error: The type of the value (String) being assigned to variable "User::UNIT_PRICE" differs from the current variable type (Decimal). Variables may not change type during execution. Variable types are strict, except for variables of type Object.
这是由于在集合中的数据默认都是 String 类型的,是不能够直接转换成我们定义的变量所指定的类型,因此需要修改我们的变量类型。
再次执行就可以看到遍历的效果,第一次 -

最后一次 -

Script Task 中的循环遍历

同样的 Object 对象,不仅仅可以在 Foreach 中循环遍历,也可以直接在 Script Task 中循环遍历。
添加一个 Script Task,把结果集对象放入变量列表中。
脚本代码如下 - 
using System.Data.OleDb;

public void Main()
{
// TODO: Add your code here
OleDbDataAdapter adapter = new OleDbDataAdapter();
DataTable dataTable = new DataTable(); adapter.Fill(dataTable, Dts.Variables["User::ORDER_SET"].Value); foreach (DataRow row in dataTable.Rows)
{
MessageBox.Show(row[] + "," + row[] + "," + row[]);
} Dts.TaskResult = (int)ScriptResults.Success;
}

一样可以实现遍历的效果 -

最后一条记录-

总结

通过讲解 Execute SQL Task 的两种查询结果返回方式 Single Row 和 Full Result Set,实际上由此引申出了何时使用 Single Row 以及 Full Result Set 的场景。熟悉和掌握这些场景可以帮助我们在复杂的 ETL 项目中找出各种不同的解决方案,可以非常灵活的解决一些实际问题。
再次,特别通过 Foreach Loop Container 以及 Script Task 学习到了两种解析 Full Result Set 的方式,其中涉及到的知识点以及细节还是比较多的,特意总结下来希望可以帮助到大家。

更多 BI 文章请参看 BI 系列随笔列表 (SSIS, SSRS, SSAS, MDX, SQL Server)  如果觉得这篇文章看了对您有帮助,请帮助推荐,以方便他人在 BIWORK 博客推荐栏中快速看到这些文章。

微软BI 之SSIS 系列 - Execute SQL Task 中的 Single Row 与 Full Result Set 的处理技巧的更多相关文章

  1. 微软BI 之SSIS 系列 - 使用 Script Task 访问非 Windows 验证下的 SMTP 服务器发送邮件

    原文:微软BI 之SSIS 系列 - 使用 Script Task 访问非 Windows 验证下的 SMTP 服务器发送邮件 开篇介绍 大多数情况下我们的 SSIS 包都会配置在 SQL Agent ...

  2. 微软BI 之SSIS 系列 - 使用 SQL Profilling Task (数据探测) 检测数据源数据

    开篇介绍 SQL Profilling Task 可能我们很多人都没有在 SSIS 中真正使用过,所以对于这个控件的用法可能也不太了解.那我们换一个讲法,假设我们有这样的一个需求 - 需要对数据库表中 ...

  3. 微软BI 之SSIS 系列 - 使用 Multicast Task 将数据同时写入多个目标表,以及写入Audit 与增量处理信息

    开篇介绍 在 SSIS Data Flow 中有一个 Multicast 组件,它的作用和 Merge, Merge Join 或者 Union All 等合并数据流组件对比起来作用正好相反.非常直观 ...

  4. 微软BI 之SSIS 系列 - 在 SQL 和 SSIS 中实现行转列的 PIVOT 透视操作

    开篇介绍 记得笔者在 2006年左右刚开始学习 SQL Server 2000 的时候,遇到一个面试题就是行转列,列转行的操作,当时写了很长时间的 SQL 语句最终还是以失败而告终.后来即使能写出来, ...

  5. 微软BI 之SSIS 系列 - MVP 们也不解的 Scrip Task 脚本任务中的一个 Bug

    开篇介绍 前些天自己在整理 SSIS 2012 资料的时候发现了一个功能设计上的疑似Bug,在 Script Task 中是可以给只读列表中的变量赋值.我记得以前在 2008 的版本中为了弄明白这个配 ...

  6. 微软BI 之SSIS 系列 - 在 SSIS 中导入 ACCESS 数据库中的数据

    开篇介绍 来自 天善学院 一个学员的问题,如何在 SSIS 中导入 ACCESS 数据表中的数据. 在 SSIS 中导入 ACCESS 数据库数据 ACCESS 实际上是一个轻量级的桌面数据库,直接使 ...

  7. 微软BI 之SSIS 系列 - 使用 Script Component Destination 和 ADO.NET 解析不规则文件并插入数据

    开篇介绍 这一篇文章是 微软BI 之SSIS 系列 - 带有 Header 和 Trailer 的不规则的平面文件输出处理技巧 的续篇,在上篇文章中介绍到了对于这种不规则文件输出的处理方式.比如下图中 ...

  8. 微软BI 之SSIS 系列 - 数据仓库中实现 Slowly Changing Dimension 缓慢渐变维度的三种方式

    开篇介绍 关于 Slowly Changing Dimension 缓慢渐变维度的理论概念请参看 数据仓库系列 - 缓慢渐变维度 (Slowly Changing Dimension) 常见的三种类型 ...

  9. 微软BI 之SSIS 系列 - Lookup 中的字符串比较大小写处理 Case Sensitive or Insensitive

    开篇介绍 前几天碰到这样的一个问题,在 Lookup 中如何设置大小写不敏感比较,即如何在 Lookup 中的字符串比较时不区分大小写? 实际上就这个问题已经有很多人提给微软了,但是得到的结果就是 C ...

随机推荐

  1. python3笔记(三)if...else、if...elif...else

    if语句 if 语句的基本用法如下: if 表达式: 语句块 其中,表达式可以是一个单纯的布尔值或变量,也可以是比较表达式或逻辑表达式(例 如:a > band a != c),如果表达式为真, ...

  2. python 全栈开发,Day94(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)

    昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...

  3. poj 3734 方块涂色 求红色 绿色方块都为偶数的方案数 (矩阵快速幂)

    N个方块排成一列 用红,蓝,绿,黄4种颜色去涂色,求红色方块 和绿色方块个数同时为偶数的 方案数 对10007取余 Sample Input 212Sample Output 2//(蓝,黄)6//( ...

  4. java快速排序引起的StackOverflowError异常

    写在前面:这篇随笔主要记录一下递归调用引起的虚拟机栈溢出的情况以及通过参数配置了虚拟机栈大小来使递归调用可以顺利执行.并没有对涉及到的一些概念进行详细的解释(因为我自己目前对这些概念并不是特别清楚), ...

  5. BZOJ1218 [HNOI2003]激光炸弹 二维前缀和

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1218 题意概括 给出一个大的矩阵,求边长为r的正方形区域的最大sum. 题解 二维前缀和然后暴力就 ...

  6. char *s 与 char s[ ]的区别

    程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其 操作方式类似于数据结构中的栈. 2.堆区( ...

  7. Luogu

    dalao们的博客a http://hzwer.com   //Orz  %%% https://oi-wiki.org  //Orz https://www.cnblogs.com/-guz/p/9 ...

  8. 团队作业第六次——团队Github实战训练

    作业格式 课程名称:软件工程1916|W(福州大学) 作业要求:团队作业第六次-团队Github实战训练 团队名称:葫芦娃队 作业目标:确定和分析选题,绘制评审表 github地址:https://g ...

  9. 电商sku商品推荐

    1.逻辑回归LR进行实时离线三级品类训练. 2.通过用户对于实时.离线三级品类的偏好进行召回. 3.通过人的特征.sku特征.人sku交互特征.以及位置手机特征通过gbdt模型进行点击量预估.

  10. 安卓,网页控件,显示网页 Android, web controls, display web pages

    安卓,网页控件,显示网页Android, web controls, display web pages 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱:313134555@qq ...