关于sql server:执行具有多个结果集的存储过程

Execute Stored Procedure with multiple result sets

我正在使用SSIS2016。我需要执行一个存储过程,该存储过程返回4个结果集。我只需要保留第一个结果集并将其写入表即可。我无法修改存储过程。我不在乎其他结果集中返回的任何数据。存储过程在SQL Server 2016数据库中。结果也将驻留在SQL Server 2016中。

我目前在OLE DB源中使用" SQL命令"数据访问模式在SSIS 2008中运行此过程,如下所示。我在For Each循环容器中将其传递给存储过程,以将一系列参数值传递给存储过程,因为我每天对不同的参数值执行多次。

1
2
3
4
5
6
SET FMTONLY OFF;

EXEC myProc
     @Param1 = ?,
     @Param2 =?,
     @Param3 = ?;

默认情况下,SSIS 2008仅返回第一个结果集,这对我有用,因为我只关心第一个结果集。

我正在使用本机OLEDB SQL Server客户端。据我了解,它改变了处理多个结果集的方式。我已经使用WITH RESULT SETS定义了第一个结果集,但是如果执行SSIS,将失败,表明需要定义其他结果集。

简而言之,在SSIS 2016中复制在SSIS 2008中起作用的最佳方法是什么?


解决方案概述

我对此问题进行了2次实验,第一个实验表明,在没有参数的存储过程的情况下,SQL Server 2016和SSIS 2016中没有任何更改,将返回第一个结果集,而其他结果集将被忽略。

第二个实验表明,使用参数时,这将引发异常,因此您必须使用WITH RESULT SETS选项定义元数据,然后删除此选项。

详细解决方案

实验1

使用SQL Server 2016和带有SSDT 2016的Visual Studio 2015进行以下实验

  • 首先,我创建了此存储过程。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    CREATE PROCEDURE sp_Test


    AS
    BEGIN

    SET NOCOUNT ON;

    SELECT TOP 10 PersonType,NameStyle,Title
      FROM [AdventureWorks2016CTP3].[Person].[Person]

    SELECT  TOP 10 PersonType,Firstname,Lastname
      FROM [AdventureWorks2016CTP3].[Person].[Person_json]
    END
    GO
  • 然后我将数据流任务添加到SSIS包中
  • 添加了OLEDB源,记录集目标
  • 在OLEDB源中,我将数据访问模式选择为SQL command
  • 使用以下命令

    1
    EXEC sp_Test
  • enter

    enter

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    ALTER PROCEDURE [dbo].[sp_Test]

        @param1 varchar(10),
        @param2 varchar(10),
        @param3 varchar(10)
    AS
    BEGIN

        SET NOCOUNT ON;


        SELECT TOP 10 PersonType,NameStyle,Title ,@param2 as 'Param'
      FROM [AdventureWorks2016CTP3].[Person].[Person]


        SELECT  TOP 10 PersonType,Firstname,Lastname,@param3 as 'Param'
      FROM [AdventureWorks2016CTP3].[Person].[Person_json]
    END

    并且我在OLEDB源代码中使用了以下SQL命令:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    EXEC sp_Test ?,?,?

    WITH RESULT SETS (
    (
        PersonType NVarchar(10),
        NameStyle NVarchar(10),
        Title  NVarchar(10),
        Param Varchar(10)
    )
    )

    我正确映射了参数。

    enter

    [OLE DB Source 2] Error: SSIS Error Code DTS_E_OLEDBERROR. An OLE DB error has occurred. Error code: 0x80040E14.
    An OLE DB record is available. Source:"Microsoft SQL Server Native Client 11.0" Hresult: 0x80040E14 Description:"EXECUTE statement failed because its WITH RESULT SETS clause specified 1 result set(s), and the statement tried to send more result sets than this.".

    之后,我尝试删除WITH RESULT SETS选项,因此命令为:

    1
    EXEC sp_Test ?,?,?

    我尝试再次执行该程序包,因此该程序包无任何错误地执行。

    结论

    尝试使用WITH RESULT SETS选项定义OLEDB Source metadata,在定义元数据之后,只需删除此选项并运行程序包,这样它将成功地获取第一个结果集。


    我知道这不完全是您要的,但是也许您可以创建另一个存储过程,该过程将仅为您返回第一个结果集? (无需触摸第一个存储的过程。)还是将数据插入表中,然后您才读取数据?