从概念上讲,您的解决方案将类似于执行源查询以生成结果集。将其存储到一个变量中,然后您需要遍历这些结果,对于每一行,您需要使用该行的值调用您的存储过程并将结果发送到一个新的 Excel 文件中。
我设想你的包裹看起来像这样
一个名为“SQL Load Recordset”的执行 SQL 任务,附加到一个名为“FELC Shred Recordset”的 Foreach 循环容器。嵌套在那里我有一个文件系统任务,名为“FST 复制模板”,它是数据流任务的优先级,名为“DFT 生成输出”。
设置
由于您是初学者,我将尝试详细解释。为了省点麻烦,请获取BIDSHelper的副本。它是一个免费的开源工具,可改善 BIDS/SSDT 的设计体验。
变量
单击控制流的背景。没有选择任何内容,右键单击并选择变量。在弹出的新窗口中,单击创建新变量的按钮 4 次。什么都不点击的原因是,在 SQL Server 2012 之前,变量创建的默认行为是在当前对象的范围内创建它们。这导致新的和有经验的开发人员都失去了很多头发。变量名区分大小写,因此也要注意这一点。
- 将变量重命名为 RecordSet。将数据类型从 Int32 更改为 Object
- 将变量 1 重命名为 ParameterValue。将数据类型从 Int32 更改为 String
- 将变量 2 重命名为 TemplateFile。将数据类型从 Int32 更改为 String。将值设置为输出 Excel 文件的路径。我用 C:\ssisdata\ShredRecordset.xlsx
- 将变量 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 Recordset
是Execute SQL Task的一个实例。在这里,我有一个简单的查询来模仿您的来源。
SELECT 'aq' AS parameterValue
UNION ALL SELECT 'dr'
UNION ALL SELECT 'tb'
在 General 选项卡上需要注意的重要一点是,我已将 ResultSet 从 切换None
到Full result set
. 这样做会使结果集选项卡从灰显变为可用。
您可以观察到我已将变量名称分配给我们在上面创建的变量 (User::RecordSet),结果名称为0
. 这很重要,因为默认值NewResultName
不起作用。
FELC 粉碎记录集
获取一个Foreach 循环容器,我们将使用它来“分解”上一步中生成的结果。
Foreach ADO Enumerator
将枚举器配置为User::RecordSet
用作您的 ADO 对象源变量。选择rows in the first table
作为您的枚举模式
在“变量映射”选项卡上,您需要选择变量User::ParameterValue
并为其分配索引 0。这将导致记录集对象中的第零个元素被分配给变量 ParameterValue。重要的是您有数据类型协议,因为 SSIS 不会在这里进行隐式转换。
FST 复制模板
这是一个文件系统任务。我们将复制我们的模板 Excel 文件,以便我们有一个命名良好的输出文件(其中包含参数名称)。将其配置为
- IsDestinationPathVariable:真
- 目标变量:用户::输出文件名
- 覆盖目标:真
- 操作:复制文件
- IsSourcePath 变量:真
- 源变量:用户::模板文件
DFT 生成输出
这是一个数据流任务。我假设您只是将结果直接转储到文件中,因此我们只需要一个OLE DB 源和一个Excel 目标
OLEDB dbo_storedProcedure1
这是使用我们在控制流中分解的参数从源系统中提取数据的地方。我将在这里写下我的查询并使用?
来表示它有一个参数。
将您的数据访问模式更改为“SQL 命令”,然后在可用的 SQL 命令文本中输入您的查询
EXECUTE dbo.storedProcedure1 ?
我单击“参数...”按钮并如图所示填写
- 参数:@parameterValue
- 变量:用户::参数值
- 参数方向:输入
将 Excel 目标连接到 OLE DB 源。双击并在 Excel 连接管理器部分中,单击新建... 确定您需要 2003 还是 2007 格式(.xls 与 .xlsx)以及您是否希望文件具有标题行。对于您的文件路径,输入您用于 @User::TemplatePath 变量的相同值,然后单击确定。
我们现在需要填充 Excel 工作表的名称。单击那个 New... 按钮,它可能会抱怨没有足够的关于映射数据类型的信息。别担心,这是半标准的。然后它将弹出一个表定义,例如
CREATE TABLE `Excel Destination` (
`name` NVARCHAR(35),
`number` INT,
`type` NVARCHAR(3),
`low` INT,
`high` INT,
`status` INT
)
“表”名称将是工作表名称,或者准确地说,是工作表中的命名数据集。我制作了我的 Sheet1 并单击“确定”。现在工作表存在,在下拉列表中选择它。我选择了 Sheet1$ 作为目标工作表名称。不确定它是否有所作为。
单击“映射”选项卡,事情应该会自动映射,所以单击“确定”。
最后
此时,如果我们运行包,它每次都会覆盖模板文件。秘密是我们需要告诉Excel Connection Manager
我们刚刚制作它不需要有硬编码的名称。
单击连接管理器选项卡中的 Excel 连接管理器。在“属性”窗口中,找到该Expressions
部分并单击省略号...
在这里我们将配置属性ExcelFilePath
,我们将使用的表达式是
@[User::OutputFileName]
如果您的图标等看起来不同,那是可以预料的。这是使用 SSIS 2012 记录的。您的工作流程在 2005 和 2008/2008R2 中将相同,只是皮肤不同。
如果你运行这个包并且它甚至没有启动并且有一个关于 ACE 12 或 Jet 4.0 的错误不可用,那么你在一台 64 位机器上并且需要告诉 BIDS/SSDT 你想在 32 位中运行模式。
确保 Run64BitRuntime 值为False
。可以通过右键单击项目找到此项目设置,展开配置属性,它将成为调试下的一个选项。
进一步阅读
可以在如何使用 SSIS 包自动执行存储过程?