我正在使用SSIS 2008.我有一个选择查询名称 sqlquery1
,它会返回一些行:
aq
dr
tb
此查询目前尚未在SSIS上实施。
我从数据流任务中的OLE DB源调用存储过程。我想将从查询中获取的数据传递给存储过程参数。
我想通过传递第一个值 aq
storedProdecure1 'aq'
然后传递第二个值 dr
storedProdecure1 'dr'
我想这会像一个循环。我需要这个,因为 OLE DB Source
通过存储过程生成的数据需要发送到另一个目的地,这必须为 sqlquery1 的每个记录完成
我想知道如何调用查询 sqlquery1
并传递其输出以调用另一个存储过程。
我如何在SSIS中执行此操作?
答案 0 :(得分:27)
从概念上讲,您的解决方案将是执行源查询以生成结果集。将其存储到变量中,然后您需要遍历这些结果,对于每一行,您都希望使用该行的值调用存储过程并将结果发送到新的Excel文件。
我设想你的包装看起来像这样
一个名为" SQL加载记录集"的执行SQL任务,附加到Foreach循环容器,名为" FELC Shred Recordset"。嵌套在那里我有一个文件系统任务,名为" FST复制模板"这是数据流任务的优先级,名为" DFT生成输出"。
由于您是初学者,我将尝试详细解释。为了省去一些麻烦,请抓一份BIDSHelper。它是一个免费的开源工具,可以改善BIDS / SSDT的设计体验。
单击控制流的背景。如果未选择任何内容,请右键单击并选择“变量”。在弹出的新窗口中,单击创建新变量4次的按钮。没有点击的原因是,在SQL Server 2012之前,变量创建的默认行为是在当前对象的范围内创建它们。对于新手和有经验的开发人员来说,这已经导致许多失去的头发。变量名称区分大小写,因此也要注意这一点。
"C:\\ssisdata\\ShredRecordset." + @[User::ParameterValue] + ".xlsx"
(或您的文件和路径)。这样做,是配置一个变量,以便随着ParameterValue的值的变化而变化。这有助于确保我们获得唯一的文件名。欢迎您根据需要更改命名约定。请注意,您需要在表达式中随时转义\
。我假设您使用的是OLE DB连接管理器。我的名字叫FOO。如果您使用ADO.NET,概念将类似,但会有与参数等有关的细微差别。
您还需要第二个连接管理器来处理Excel。如果SSIS对于数据类型是不稳定的,那么当你在数据类型上重新沉睡时,Excel会让你精神错乱 - 在后面与你同行。我们将等待并让数据流实际创建此Connection Manager以确保我们的类型良好。
SQL Load Recordset
是Execute SQL Task的一个实例。在这里,我有一个简单的查询来模仿您的来源。
SELECT 'aq' AS parameterValue
UNION ALL SELECT 'dr'
UNION ALL SELECT 'tb'
“常规”标签上需要注意的重要一点是,我已将ResultSet从None
切换为Full result set
。这样做会使“结果集”选项卡从灰色变为可用。
您可以观察到我已将变量名称分配给上面创建的变量(User :: RecordSet),结果名称为0
。这很重要,因为默认值NewResultName
无效。
抓住Foreach Loop Container,然后我们将其用于" shred"在前一步骤中生成的结果。
将枚举数配置为Foreach ADO Enumerator
使用User::RecordSet
作为ADO对象源变量。选择rows in the first table
作为枚举模式
在“变量映射”选项卡上,您需要选择变量User::ParameterValue
并为其指定索引0.这将导致记录集对象中的zerotth元素被分配给变量ParameterValue。由于SSIS不会在此处进行隐式转换,因此您必须拥有数据类型协议。
这是File System Task。我们将复制我们的模板Excel文件,以便我们有一个命名良好的输出文件(其中包含参数名称)。将其配置为
这是Data Flow Task。我假设您只是将结果直接转储到文件中,因此我们只需要OLE DB Source和Excel Destination
这是您使用我们在控制流中粉碎的参数从源系统中提取数据的位置。我将在此处编写查询并使用?
表示它有一个参数。
将您的数据访问模式更改为" SQL命令"并在可用的SQL命令文本中,输入您的查询
EXECUTE dbo.storedProcedure1 ?
我点击参数...按钮并按如图所示填写
将Excel目标连接到OLE DB源。双击并在“Excel连接管理器”部分中,单击“新建...”确定您是否需要2003或2007格式(.xls与.xlsx)以及是否希望文件具有标题行。对于File Path,输入与@User :: TemplatePath变量相同的值,然后单击OK。
我们现在需要填充Excel工作表的名称。单击New ...按钮,可能会发现没有足够的有关映射数据类型的信息。不要担心,这是半标准的。然后它会弹出一个像
这样的表定义CREATE TABLE `Excel Destination` (
`name` NVARCHAR(35),
`number` INT,
`type` NVARCHAR(3),
`low` INT,
`high` INT,
`status` INT
)
"表" name将成为工作表名称,或者恰好是工作表中的命名数据集。我制作了Sheet1并单击OK。既然工作表存在,请在下拉列表中选择它。我使用Sheet1 $作为目标工作表名称。不确定它是否有所作为。
单击Mappings选项卡,事情应该自动映射,然后单击OK。
此时,如果我们运行包,它每次都会覆盖模板文件。秘诀是我们需要告诉Excel Connection Manager
我们刚刚提出它不需要硬编码的名称。
在“连接管理器”选项卡中的Excel连接管理器上单击一次。在“属性”窗口中,找到Expressions
部分,然后点击省略号...
这里我们将配置属性ExcelFilePath
,我们将使用的表达式是
@[User::OutputFileName]
如果您的图标等不同,那就是预期的。这是使用SSIS 2012记录的。您的工作流程在2005和2008 / 2008R2中将是相同的,只是皮肤不同。
如果您运行此软件包并且它甚至没有启动并且有关于ACE 12或Jet 4.0的错误,那么您将使用64位计算机,并且需要告诉BIDS / SSDT您想要的以32位模式运行。
确保Run64BitRuntime值为False
。右键单击项目可以找到此项目设置,展开配置属性,它将是调试下的一个选项。
可以在How to automate the execution of a stored procedure with an SSIS package?
上找到粉碎记录集对象的不同示例