SSIS OLE DB Source调用存储过程BIGINT输出参数类型不匹配报错
SSIS OLE DB Source调用带BIGINT输出参数存储过程报类型不匹配错误
问题描述
开发面向SQL Server 2016的SSIS包时,需要在Data Flow Task(数据流任务)的OLE DB Source组件中调用带输出参数的存储过程,将输出参数值赋值给SSIS变量。已将对应SSIS变量定义为Int64类型,存储过程内的输出参数定义为BIGINT类型,但执行包时SSIS持续返回如下错误:
错误:赋值给变量"User::SomeOutput"的值类型为Decimal,与变量当前的Int64类型不匹配。执行期间变量不可变更类型,除Object类型变量外,所有变量类型均执行强类型校验。
将SSIS本地变量类型改为Decimal后报错消失,但业务需求要求该值必须为BIGINT/Int64类型,无法接受将变量改为Decimal的处理方式。
复现步骤
按以下配置操作即可稳定复现问题:
- 创建测试存储过程,代码如下:
CREATE OR ALTER PROCEDURE [dbo].[Pr_GetTestProcedure] @SomeOutput BIGINT = NULL OUTPUT AS SET @SomeOutput = 8 SELECT 'Yes' AS Something GO
- 创建SSIS本地用户变量,类型设置为Int64
- 新建数据流任务,添加OLE DB Source组件,配置为SQL命令模式调用上述存储过程
- 在OLE DB Source的参数映射页,将存储过程的
@SomeOutput输出参数映射到之前创建的Int64类型用户变量
完成配置后执行包,即可触发前述类型不匹配错误。
根因分析
这是SQL Server OLE DB驱动的历史已知问题:当存储过程同时返回结果集、未关闭行计数反馈时,驱动会错误地将BIGINT类型的输出参数元数据识别为Decimal(20,0),而非对应的8字节有符号整数类型,因此触发SSIS的强类型校验失败。
可行解决方案
按侵入性从低到高排序,可选择以下任意一种方案修复:
- 方案1:在存储过程开头添加
SET NOCOUNT ON;语句,关闭DONE_IN_PROC消息(影响行数返回)即可修正驱动的元数据识别错误。修改后的存储过程示例:
CREATE OR ALTER PROCEDURE [dbo].[Pr_GetTestProcedure] @SomeOutput BIGINT = NULL OUTPUT AS SET NOCOUNT ON; SET @SomeOutput = 8 SELECT 'Yes' AS Something GO
该方案不需要修改任何现有SSIS包配置,是优先推荐的修复方式。
- 方案2:调整存储过程逻辑,不使用输出参数返回BIGINT值,改为将该值作为返回结果集的一列输出,在数据流中通过派生列转换、记录集目标等组件完成SSIS变量赋值。
- 方案3:如果存储过程无修改权限,可先将输出参数映射到Decimal类型的中间SSIS变量,再通过表达式任务或脚本任务将Decimal值显式转换为Int64类型,赋值给业务需要的目标Int64变量即可,转换前建议增加数值范围校验,避免溢出错误。
内容的提问来源于stack exchange,提问作者DeathAndTaxes
相关产品推荐
相关产品推荐

