SSIS中通过变量执行跨库Update时如何获取并保存更新行数?
解决SSIS Foreach循环中捕获动态SQL更新行数并记录的方案
我刚好处理过几乎一模一样的场景,给你一步步拆解怎么实现——核心就是让Execute SQL Task返回受影响行数,把值存到变量,再用额外任务把这个值写入日志表或平面文件:
1. 先准备存储行数的变量
在SSIS包的变量面板里新增一个整数类型的变量,比如命名为User::RowCountUpdated,作用域设为包级别(这样Foreach循环和后续的日志任务都能访问到)。
2. 配置Execute SQL Task返回更新行数
因为你用的是动态源连接(SourceConnString)和变量存储的Update语句,配置时要注意这几个关键设置:
- ConnectionType:选你实际用的连接类型(比如OLE DB,大多数SQL Server场景用这个)
- Connection:选择基于
SourceConnString的那个连接管理器(要确保这个连接已经设置为通过变量获取连接字符串) - SQLSourceType:选
Variable,然后关联你的UpdateVariable - ResultSet:一定要选
Single row——因为我们要捕获的是一个单一的数值(受影响行数) - 切换到Result Set标签页:
- 点击「Add」,
Result Name填0(Execute SQL返回的第一列就是受影响行数,用序号0指代),Variable Name选刚才创建的User::RowCountUpdated
- 点击「Add」,
小提示:如果是SQL Server,
UPDATE语句执行后默认会返回受影响行数,不需要修改你的Update语句;如果是Oracle这类数据库,可能需要在Update语句末尾加SELECT SQL%ROWCOUNT FROM DUAL来返回行数。
3. 添加日志写入任务(分两种场景)
在Foreach循环容器里,把这个任务放在Execute SQL Task的后面(确保先执行Update,再记录行数):
场景A:写入到日志表
新增一个Execute SQL Task(比如命名为InsertRowCountToLog):
- 连接用固定的日志库连接管理器(日志表的位置一般是固定的吧?比如DestDB2里的专门日志表)
- SQLSourceType选
Direct Input,写入插入语句,示例:INSERT INTO UpdateExecutionLog (SourceDatabaseName, ExecutionTime, RowsUpdated) VALUES (?, GETDATE(), ?) - 切换到Parameter Mapping标签页,添加两个参数:
- 第一个参数:关联你Foreach循环里用来遍历源数据库名称的变量(比如
User::SourceDBName),类型选对应字段的类型(比如NVARCHAR),参数名填0(OLE DB参数按顺序用0、1、2...) - 第二个参数:关联
User::RowCountUpdated,类型选INT,参数名填1
- 第一个参数:关联你Foreach循环里用来遍历源数据库名称的变量(比如
这样每次循环都会把当前源库名、执行时间、更新行数插入到日志表。
场景B:写入到平面文件
用Data Flow Task来实现更灵活:
- 新增一个Data Flow Task,拖入一个Script Component,选择「Source」类型
- 进入Script Component的编辑界面,在Inputs and Outputs里,给
Output0添加三个输出列:SourceDBName(字符串类型)、ExecutionTime(日期类型)、RowsUpdated(整数类型) - 编辑脚本(以C#为例),在
CreateNewOutputRows方法里把变量值赋值给输出列:// 从SSIS变量中获取值 string sourceDbName = Variables.SourceDBName; DateTime execTime = DateTime.Now; int updatedRows = Variables.RowCountUpdated; // 生成一行输出数据 Output0Buffer.AddRow(); Output0Buffer.SourceDBName = sourceDbName; Output0Buffer.ExecutionTime = execTime; Output0Buffer.RowsUpdated = updatedRows; - 最后拖入一个Flat File Destination,指向你要写入的平面文件,把输出列和文件的列对应绑定即可。
4. 几个注意点
- 确保
SourceConnString的变量在Foreach循环中能正确遍历每个源数据库的连接字符串,避免连接失败 - 如果你的Update语句是动态拼接的(比如包含动态表名),要注意SQL注入风险(内部环境相对安全,但也要尽量用参数化的方式)
- 测试时可以先单步执行循环,查看
RowCountUpdated变量是否正确获取到值,再验证日志任务是否正常写入
内容的提问来源于stack exchange,提问作者Isha
相关产品推荐
相关产品推荐

