捕获事务中受影响的第一行并分配给 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 Task
和 Execute 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::RowCountNewADO
和 User::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>
我正在 运行从 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 Task
和 Execute 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::RowCountNewADO
和 User::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>