【问题标题】:How to Add the Result Set from a T-SQL Statement to a Data Flow?如何将 T-SQL 语句的结果集添加到数据流中?
【发布时间】:2015-06-04 04:12:57
【问题描述】:

我有一个简单的 SSIS 包,我想把它复杂一点。

现在,它在 OLE DB 源中执行存储过程,并将存储过程返回的行添加到数据流中。然后,对于返回的每一行,它执行 OLE DB 命令转换,执行第二个存储过程(在第二个数据库中),将源中的列作为参数传递。

第二个存储过程执行同步功能,我想记录添加、删除和更新的总数。 “同步”存储过程使用 MERGE 语句的 OUTPUT 子句获取此数据并将其作为结果集返回。

我看不到从 OLE DB 命令转换中获取此结果集的方法。它不允许我添加输出列。

没有添加脚本转换,有没有办法让我记录添加、删除和更新列的总数?

【问题讨论】:

    标签: ssis


    【解决方案1】:

    这并不像应有的那么简单。否则我需要回到 SSIS 课程。

    OLE DB 命令组件无法向数据流添加新行,因为它是一个同步组件。

    它也无法向数据流添加新列。这是不直观的第一件事。因此,您将在我的源代码中看到,我添加了类型为 nvarchar(10)/字符串长度为 10 的 ActionName 列。如果您愿意,可以在 OLE DB 命令组件之前的派生列转换中添加该列。

    由于我无法向数据流添加行,这意味着我只能为我的 proc 使用 OUTPUT 参数,而不是使用它可以生成的记录集。也许您的存储过程一次只允许更改一行,这没关系,但对我来说有一般的代码味道。

    表定义和设置

    CREATE TABLE dbo.so_27932430
    (
        SourceId int NOT NULL
    ,   SourceValue varchar(20) NOT NULL
    );
    GO
    INSERT INTO
        dbo.so_27932430
    (SourceId, SourceValue)
    VALUES
        (1, 'No change')
    ,   (3,'Changed');
    

    存储过程

    CREATE PROCEDURE
        dbo.merge_27932430
    (
        @SourceId int
    ,   @SourceValue varchar(20)
    ,   @ActionName nvarchar(10) OUTPUT
    )
    AS
    BEGIN
        SET NOCOUNT ON;
    
        DECLARE
            @BloodyHack table
        (
            ActionName nvarchar(10) NOT NULL
        ,   SourceId int NOT NULL
        );
    
        MERGE
            dbo.so_27932430 AS T
        USING
        (
            SELECT
                D.SourceId
            ,   D.SourceValue
            FROM
            (
                SELECT @SourceId, @SourceValue
            ) D(SourceId, SourceValue)
        ) AS S
        ON
        (
            T.SourceId = S.SourceId
        )
        WHEN
            MATCHED 
                AND T.SourceValue <> S.SourceValue
            THEN
            UPDATE
            SET
                T.SourceValue = S.SourceValue
        WHEN
            NOT MATCHED THEN
            INSERT
            (
                SourceId
            ,   SourceValue
            )
            VALUES
            (
                SourceId
            ,   SourceValue
            )
        OUTPUT 
            $action, S.SourceId
        INTO
            @BloodyHack;
    
        /* Pick one, any one*/
        SELECT
            @ActionName = BH.ActionName
        FROM
            @BloodyHack AS BH
    
    END
    

    来源查询

    SELECT
        D.SourceId
    ,   D.SourceValue
    ,   CAST(NULL AS nvarchar(10)) AS ActionName
    FROM
    (
        VALUES
            (1, 'No change')
        ,   (2, 'I am new')
        ,   (3,'I Changed')
    ) D(SourceId, SourceValue);
    

    OLE DB 命令设置

    EXECUTE dbo.merge_27932430 @SourceId = ?, @SourceValue = ?, @ActionName = ? OUTPUT;
    

    结果

    参考文献

    比米尔

    假设您有免费的BidsHelper,则使用以下 Biml 生成此包。

    <Biml xmlns="http://schemas.varigence.com/biml.xsd">
        <Connections>
            <OleDbConnection Name="CM_OLE" ConnectionString="Data Source=localhost\dev2014;Initial Catalog=tempdb;Provider=SQLNCLI10.1;Integrated Security=SSPI;Auto Translate=False;" />
        </Connections>
        <Packages>
            <Package ConstraintMode="Linear" Name="so_27932430">
                <Variables>
                    <Variable DataType="String" Name="QuerySource">
                        <![CDATA[SELECT
        D.SourceId
    ,   D.SourceValue
    ,   CAST(NULL AS nvarchar(10)) AS ActionName
    FROM
    (
        VALUES
            (1, 'No change')
        ,   (2, 'I am new')
        ,   (3,'I Changed')
    ) D(SourceId, SourceValue);
    ]]></Variable>
                    <Variable DataType="String" Name="QueryCommand">EXECUTE dbo.merge_27932430 @SourceId = ?, @SourceValue = ?, @ActionName = ? OUTPUT;</Variable>
                </Variables>
                <Tasks>
                    <Dataflow Name="DFT OLEDB Test">
                        <Transformations>
                            <OleDbSource ConnectionName="CM_OLE" Name="OLESRC GenData">
                                <VariableInput VariableName="User.QuerySource" />
                            </OleDbSource>
                            <OleDbCommand ConnectionName="CM_OLE" Name="OLECMD Test">
                                <DirectInput>EXECUTE dbo.merge_27932430 @SourceId = ?, @SourceValue = ?, @ActionName = ? OUTPUT;</DirectInput>
                                <Parameters>
                                    <Parameter SourceColumn="SourceId" DataType="Int32" TargetColumn="@SourceId"></Parameter>
                                    <Parameter SourceColumn="SourceValue" DataType="AnsiString" Length="20" TargetColumn="@SourceValue"></Parameter>
                                    <Parameter SourceColumn="ActionName" DataType="String" Length="10" TargetColumn="@ActionName"></Parameter>
                                </Parameters>
                            </OleDbCommand>
                            <DerivedColumns Name="DER PlaceHolder" />
                        </Transformations>
                    </Dataflow>
                </Tasks>
            </Package>
        </Packages>
    </Biml>
    

    【讨论】:

    • 谢谢。我在这里可能会走运。存储过程的输出仅用于记录添加、删除和不匹配的行数。听起来它可以与三个 OUTPUT 参数一起使用。不理想,正如你所说。如果我真的需要返回不止一行(我几乎做到了),它就行不通了。
    猜你喜欢
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    相关资源
    最近更新 更多