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

1 t-sql sql-server ssis stored-procedures

我有一个存储过程,使用执行SQL任务通过SQL SSIS执行.

任务包括以下内容:

USE [OPPY_DWUSD]
GO
DECLARE @return_value int
EXEC    @return_value = [dbo].[generate_merge_scdbk]
    @Schema = N'dim',
    @Dimension = N'VARIETY',
    @ETLSchema = N'stg',
    @ETLTable = N'vw_VARIETY',
    @Execute = 1

SELECT  'Return Value' = @return_value
GO
Run Code Online (Sandbox Code Playgroud)

现在,我有这种设置的方式,我有多个具有相同代码但不同值的执行SQL任务,大约20个执行SQL任务.

是否有更清洁的方法来解决这个问题?

小智 6

这是一种做到这一点的方法.该示例使用SSIS 2008 R2和SQL Server 2012后端.

创建一个表来存储参数值.假设表名是dbo.SProcValues.根据您的存储过程定义,表模式将如下所示.

CREATE TABLE dbo.SProcValues(
    Id int IDENTITY(1,1) NOT NULL,
    SProcName nvarchar(40) NOT NULL,
    SchemaName nvarchar(20) NOT NULL,
    Dimension nvarchar(40) NOT NULL,
    ETLSchema nvarchar(20) NOT NULL,
    ETLTable nvarchar(40) NOT NULL,
    IsExecute bit NOT NULL
) 
GO
Run Code Online (Sandbox Code Playgroud)

让我们使用以下脚本插入一些示例数据.

INSERT INTO dbo.SProcValues 
    (SProcName, SchemaName, Dimension, ETLSchema, ETLTable, IsExecute) VALUES
    ('dbo.sp_generate_merge', 'dim1', 'dimension1', 'stg1', 'table1', 1),
    ('dbo.sp_generate_merge_scdbk', 'dim2', 'dimension2', 'stg2', 'table2', 1),
    ('dbo.sp_generate_merge_scdbk', 'dim3', 'dimension3', 'stg3', 'table3', 0),
    ('dbo.sp_generate_merge', 'dim4', 'dimension4', 'stg4', 'table4', 0);
GO
Run Code Online (Sandbox Code Playgroud)

在SSIS包上,假设您已经建立了数据源和连接管理器.创建以下变量.变量SProcValues将保存我们存储在上述表中的参数集.变量SQLInnerQuery将保存稍后将在内部执行SQL任务中使用的查询.其他变量与表中可用的每个列相关,因此我们可以遍历每一行并将其保存在变量中.

将以下查询粘贴到变量SQLGetParameters的值中

SELECT SProcName, SchemaName, Dimension, ETLSchema, ETLTable, IsExecute FROM dbo.SProcValues

变量

选择变量SQLInnerQuery,然后按F4查看属性.将属性EvaluateAsExpression设置为True,然后针对Expression属性单击省略号按钮.

SQLInnerQuery

我们需要设置一个表达式,该表达式将评估EXEC存储过程语句,该语句稍后可以提供给内部的Execute SQL Task.设置以下表达式.

"EXEC " + @[User::SProcName] + " @Schema = ?, @Dimension = ?, @ETLSchema = ?, @ETLTable = ?, @IsExecute = ?"

如果单击编辑器上的"评估表达式"按钮,则可以查看表达式将评估的内容.您还会注意到下面的屏幕截图中没有存储过程名称,因为包变量SProcName当前没有任何值.在运行时,将为SProcName分配表中的值,该表达式将自动解析. 表达

在SSIS包上,拖放执行SQL任务.此任务将运行以下查询以获取存储在表dbo.SProcValues中的参数值列表.在Execute SQL Task上配置General页面,如下所示.该示例使用OLEDB连接,连接管理器/数据源名为Practice.

首先执行SQL任务 - 常规

配置"执行SQL任务"的"结果集"页面,将查询中的结果集存储到对象变量中.

首先执行SQL任务 - 结果集

现在,第一个执行SQL任务被配置为获取应传递给存储过程的参数值列表,您需要遍历记录.

拖放Foreach循环容器.将Execute SQL Task的优先级容器连接到Foreach循环容器.配置Foreach循环容器的Collection页面,如下所示.我们使用ADO枚举器循环遍历结果集.

Foreach循环 - 集合

在Foreach循环容器上配置Variable Mappings页面,如下所示.当我们遍历每一行时,我们将列值存储在各自的变量中,以便我们可以将它传递给下一个执行SQL任务来运行存储过程.

Foreach循环 - 变量映射

在Foreach循环容器中拖放一个执行SQL任务,以便每次循环结果集中的一行时执行此任务.配置执行SQL任务,如下所示.

注意

您可能希望根据您的要求在此第二个执行SQL任务上配置ResultSet属性.如果选择ResultSet,则需要配置适当的对象变量以接受结果集.对于这个例子,我把它留作无.

第二次执行SQL任务 - 常规

配置要作为参数传递给存储过程的值.

第二次执行SQL任务 - 参数映射

最后,控制流程看起来像这样.

控制流

当程序包运行时,循环将执行存储过程,因为上面提到的SELECT查询返回了许多记录,前提是您在表中定义的所有存储过程在数据库中都可用.我创建了存储过程dbo.sp_generate_merge_scdbkdbo.sp_generate_merge使用相同的参数定义.这就是包成功执行的原因.

执行