捕获事务中受影响的第一行并分配给 SSIS 变量

Capture first rows affected in transaction and assign to SSIS variable

我正在 运行从 SSIS Execute T-SQL Statement 任务中执行以下 T-SQL 语句:

BEGIN TRANSACTION
BEGIN TRY

    INSERT  FooTable (...)
    SELECT  ...
    FROM    FooTableStaging ts
    WHERE NOT EXISTS (
        SELECT  id
        FROM    FooTable
        WHERE   id=ts.id
    );

    -- reset staging table
    DELETE
    FROM    FooTableStaging
    ;

    COMMIT TRANSACTION

END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION
    ...
END CATCH

当脚本 运行 来自 SSMS 时,它 returns 有两个计数:

(69 row(s) affected)

(217 row(s) affected)

如何捕获第一个计数并将其分配给 SSIS 变量?在这种情况下 @@ROWCOUNT 不等于 217 吗?

** 编辑 **

使用 OLE DB 连接类型。

可能有几种方法可以做到,但我认为最简单的方法是将以下 3 行添加到脚本中

-- line 1  Make a variable to hold the desired value
DECLARE @NewRowCount int;
BEGIN TRANSACTION
BEGIN TRY

    INSERT  FooTable (...)
    SELECT  ...
    FROM    FooTableStaging ts
    WHERE NOT EXISTS (
        SELECT  id
        FROM    FooTable
        WHERE   id=ts.id
    );

    -- Line 2  Capture the intended count
    SELECT @NewRowCount = @@ROWCOUNT;

    -- reset staging table
    DELETE
    FROM    FooTableStaging
    ;

    COMMIT TRANSACTION

END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION
    ...
END CATCH

-- Line 3 Make a single row return statement
SELECT @NewRowCount AS NewRowCount;

现在您需要使执行 SQL 任务成为 "hear" 行,因此将结果集类型从默认的 None 更改为 SingleRow。在“结果集”选项卡中,单击“添加”按钮,结果集名称 0 将映射到 User::MyVariableCount 或您所称的任何名称。

执行T-SQL语句任务与执行SQL任务

在 SSIS 域中有两个名称相似的任务可供我们使用。更常见的 Execute SQL TaskExecute T-SQL Statement Task 在数据库 Maintenance/Other 任务下可用(取决于您的 SSIS 版本)。

执行 SQL 任务可以使用 OLE、ODBC 或 ADO.NET 连接管理器。 T-SQL 任务仅支持 ADO.NET 连接管理器。

执行 SQL 任务能够接受参数和 return 结果集,并使用 SSIS 变量或文件作为查询源。 Execute T-TSQ 任务不接受任何参数,不提供输出并且只能使用硬编码查询。

鉴于上述情况,我知道在任何情况下我都会使用 Execute T-SQL Statement Task 而不是 Execute SQL Task。将您现有的任务换成使用执行 SQL 任务,您就可以开始了。否则,答案是做不到。

从执行 SQL 任务获取结果集的演示

它对我有用,不确定您 运行 将 Execute SQL Task 执行到 return 单行结果集时遇到了什么错误。

为了简化流程,除了上面的最后一行 SQL 之外,我跳过了所有内容来进行查询 SELECT 1 AS NewRowCount;

我创建了两个 SSIS 变量,User::RowCountNewADOUser::RowCountNewOLE 都是 Int32 类型

我的执行SQL任务配置如图

结果集选项卡就这样设置了

自己试试

如果我不演示 Biml,这对我来说就不是一个合适的 SSIS 答案。商业智能标记语言 Biml 允许我描述 SSIS 包,以便您可以在您的环境中重新创建它。您需要做的就是下载 BIDS Helper 它是 Visual Studio 的免费 add-on 以帮助您获得 SSIS/SSRS/SSAS 开发经验。

安装后,右键单击您的 SSIS 项目并select添加新的 Biml 文件。

将以下内容粘贴到 BimlScript.biml 文件中

编辑第 3 行和第 4 行以指向有效服务器(除非您 运行 在 dev2014 的本地计算机上命名实例)并保存。

右键单击 BimlScript.biml 和 select 生成 SSIS 包

<Biml xmlns="http://schemas.varigence.com/biml.xsd">
    <Connections>
        <AdoNetConnection Name="CM_ADO_DB" ConnectionString="Data Source=localhost\dev2014;Integrated Security=SSPI;Connect Timeout=30;Database=msdb;" Provider="SQL"  />
        <OleDbConnection Name="CM_OLE" ConnectionString="Data Source=localhost\dev2014;Initial Catalog=tempdb;Provider=SQLNCLI11.0;Integrated Security=SSPI;"/>
    </Connections>    
    <Packages>
        <Package Name="so_34443637" ConstraintMode="Linear">
            <Variables>
                <Variable DataType="Int32" Name="RowCountNewADO">0</Variable>
                <Variable DataType="Int32" Name="RowCountNewOLE">0</Variable>
            </Variables>
            <Tasks>
                <ExecuteSQL 
                    ConnectionName="CM_ADO_DB" 
                    ResultSet="SingleRow"
                    Name="SQL - Get Row Count ADO">
                    <DirectInput>SELECT 1 AS NewRowCount;</DirectInput>
                    <Results>
                        <Result VariableName="User.RowCountNewADO" Name="0" />
                    </Results>
                </ExecuteSQL>
                <ExecuteSQL 
                    ConnectionName="CM_OLE" 
                    ResultSet="SingleRow"
                    Name="SQL - Get Row Count OLE">
                    <DirectInput>SELECT 1 AS NewRowCount;</DirectInput>
                    <Results>
                        <Result VariableName="User.RowCountNewOLE" Name="0" />
                    </Results>
                </ExecuteSQL>
                <ExecuteSQL ConnectionName="CM_OLE" Name="Breakpoint">
                    <DirectInput>SELECT 1 AS x;</DirectInput>
                </ExecuteSQL>
            </Tasks>
        </Package>
    </Packages>
</Biml>