4

我正在使用 SSIS 2008。我有一个sqlquery1返回一些行的选择查询名称:

aq
dr
tb

此查询目前未在 SSIS 上实现。

我从数据流任务中的 OLE DB 源调用存储过程。我想将从查询中获得的数据传递给存储过程参数。

例子:

我想通过传递第一个值来调用存储过程aq

storedProdecure1 'aq'

然后传递第二个值dr

storedProdecure1 'dr'

我想这将是一个循环。我需要这个,因为OLE DB Source通过存储过程生成的数据需要发送到另一个目的地,并且必须为sqlquery1的每条记录完成。

我想知道如何调用查询sqlquery1并将其输出传递给另一个存储过程。

我需要如何在 SSIS 中执行此操作?

4

1 回答 1

31

从概念上讲,您的解决方案将类似于执行源查询以生成结果集。将其存储到一个变量中,然后您需要遍历这些结果,对于每一行,您需要使用该行的值调用您的存储过程并将结果发送到一个新的 Excel 文件中。

我设想你的包裹看起来像这样

一个名为“SQL Load Recordset”的执行 SQL 任务,附加到一个名为“FELC Shred Recordset”的 Foreach 循环容器。嵌套在那里我有一个文件系统任务,名为“FST 复制模板”,它是数据流任务的优先级,名为“DFT 生成输出”。

控制流

设置

由于您是初学者,我将尝试详细解释。为了省点麻烦,请获取BIDSHelper的副本。它是一个免费的开源工具,可改善 BIDS/SSDT 的设计体验。

变量

单击控制流的背景。没有选择任何内容,右键单击并选择变量。在弹出的新窗口中,单击创建新变量的按钮 4 次。什么都不点击的原因是,在 SQL Server 2012 之前,变量创建的默认行为是在当前对象的范围内创建它们。这导致新的和有经验的开发人员都失去了很多头发。变量名区分大小写,因此也要注意这一点。

  1. 将变量重命名为 RecordSet。将数据类型从 Int32 更改为 Object
  2. 将变量 1 重命名为 ParameterValue。将数据类型从 Int32 更改为 String
  3. 将变量 2 重命名为 TemplateFile。将数据类型从 Int32 更改为 String。将值设置为输出 Excel 文件的路径。我用 C:\ssisdata\ShredRecordset.xlsx
  4. 将变量 4 重命名为 OutputFileName。将数据类型从 Int32 更改为 String。在这里,我们将做一些稍微高级的事情。单击变量并按 F4 以显示“属性”窗口。将 EvaluateAsExpression 的值更改为 True。在 Expression 中,将其设置为"C:\\ssisdata\\ShredRecordset." + @[User::ParameterValue] + ".xlsx"(或任何您的文件和路径)。这样做的目的是将变量配置为随着 ParameterValue 的值的变化而变化。这有助于确保我们获得唯一的文件名。欢迎您根据需要更改命名约定。请注意,您需要在\任何时候在表达式中转义。

连接管理器

我假设您使用的是 OLE DB 连接管理器。我的名字叫 FOO。如果您使用的是 ADO.NET,则概念将是相似的,但与参数等有关的细微差别。

您还需要第二个连接管理器来处理 Excel。如果 SSIS 对数据类型喜怒无常,那么 Excel 会在你沉睡于数据类型时,用叉子在背后捅你一刀。我们将等待,让数据流真正创建这个连接管理器,以确保我们的类型是好的。

源查询到结果集

SQL Load RecordsetExecute SQL Task的一个实例。在这里,我有一个简单的查询来模仿您的来源。

SELECT 'aq' AS parameterValue
UNION ALL SELECT 'dr'
UNION ALL SELECT 'tb'

执行sql任务常规选项卡

在 General 选项卡上需要注意的重要一点是,我已将 ResultSet 从 切换NoneFull result set. 这样做会使结果集选项卡从灰显变为可用。

执行sql任务结果集选项卡 您可以观察到我已将变量名称分配给我们在上面创建的变量 (User::RecordSet),结果名称为0. 这很重要,因为默认值NewResultName不起作用。

FELC 粉碎记录集

获取一个Foreach 循环容器,我们将使用它来“分解”上一步中生成的结果。

Foreach ADO Enumerator将枚举器配置为User::RecordSet用作您的 ADO 对象源变量。选择rows in the first table作为您的枚举模式

使用 Foreach ADO 枚举器并使用 User::RecordSet 作为源。 选择第一个表中的行

在“变量映射”选项卡上,您需要选择变量User::ParameterValue并为其分配索引 0。这将导致记录集对象中的第零个元素被分配给变量 ParameterValue。重要的是您有数据类型协议,因为 SSIS 不会在这里进行隐式转换。

将 User::ParameterValue 分配为变量映射选项卡上的第 0 个索引

FST 复制模板

这是一个文件系统任务。我们将复制我们的模板 Excel 文件,以便我们有一个命名良好的输出文件(其中包含参数名称)。将其配置为

  • IsDestinationPathVariable:真
  • 目标变量:用户::输出文件名
  • 覆盖目标:真
  • 操作:复制文件
  • IsSourcePath 变量:真
  • 源变量:用户::模板文件

在此处输入图像描述

DFT 生成输出

这是一个数据流任务。我假设您只是将结果直接转储到文件中,因此我们只需要一个OLE DB 源和一个Excel 目标

基本数据流

OLEDB dbo_storedProcedure1

这是使用我们在控制流中分解的参数从源系统中提取数据的地方。我将在这里写下我的查询并使用?来表示它有一个参数。

将您的数据访问模式更改为“SQL 命令”,然后在可用的 SQL 命令文本中输入您的查询

EXECUTE dbo.storedProcedure1 ?

OLEDB 源到 Excel 目标

我单击“参数...”按钮并如图所示填写

  • 参数:@parameterValue
  • 变量:用户::参数值
  • 参数方向:输入

参数配置

将 Excel 目标连接到 OLE DB 源。双击并在 Excel 连接管理器部分中,单击新建... 确定您需要 2003 还是 2007 格式(.xls 与 .xlsx)以及您是否希望文件具有标题行。对于您的文件路径,输入您用于 @User::TemplatePath 变量的相同值,然后单击确定。

Excel 连接管理器

我们现在需要填充 Excel 工作表的名称。单击那个 New... 按钮,它可能会抱怨没有足够的关于映射数据类型的信息。别担心,这是半标准的。然后它将弹出一个表定义,例如

CREATE TABLE `Excel Destination` (
    `name` NVARCHAR(35),
    `number` INT,
    `type` NVARCHAR(3),
    `low` INT,
    `high` INT,
    `status` INT
)

“表”名称将是工作表名称,或者准确地说,是工作表中的命名数据集。我制作了我的 Sheet1 并单击“确定”。现在工作表存在,在下拉列表中选择它。我选择了 Sheet1$ 作为目标工作表名称。不确定它是否有所作为。

Excel 目标编辑器

单击“映射”选项卡,事情应该会自动映射,所以单击“确定”。

最后

此时,如果我们运行包,它每次都会覆盖模板文件。秘密是我们需要告诉Excel Connection Manager我们刚刚制作它不需要有硬编码的名称。

单击连接管理器选项卡中的 Excel 连接管理器。在“属性”窗口中,找到该Expressions部分并单击省略号...在这里我们将配置属性ExcelFilePath,我们将使用的表达式是 @[User::OutputFileName]

如果您的图标等看起来不同,那是可以预料的。这是使用 SSIS 2012 记录的。您的工作流程在 2005 和 2008/2008R2 中将相同,只是皮肤不同。

如果你运行这个包并且它甚至没有启动并且有一个关于 ACE 12 或 Jet 4.0 的错误不可用,那么你在一台 64 位机器上并且需要告诉 BIDS/SSDT 你想在 32 位中运行模式。

确保 Run64BitRuntime 值为False。可以通过右键单击项目找到此项目设置,展开配置属性,它将成为调试下的一个选项。

32位属性设置

进一步阅读

可以在如何使用 SSIS 包自动执行存储过程?

于 2012-12-20T16:58:46.133 回答