只是偶然发现了一个简单的错误,它提示了一个有趣的问题.环境:VS 2010,NET.4,C#.从SQL sproc获取返回值会产生"指定的强制转换无效"异常:
cm.Parameters.Add( "@si", SqlDbType.SmallInt ).Direction= ParameterDirection.ReturnValue;
..
cm.ExecuteNonQuery( );
short siRetVal= (short) cm.Parameters[0].Value; // exception here
Run Code Online (Sandbox Code Playgroud)
由于代码在调试模式下运行并在该行中断,我输入了立即窗口:
?(short) cm.Parameters[0].Value
Run Code Online (Sandbox Code Playgroud)
结果是:
Cannot unbox 'cm.Parameters[0].Value' as a 'short'
Run Code Online (Sandbox Code Playgroud)

好吧,SQL sproc返回一个32位int(不是short我最初想到的16位),这解释了异常.应该为此参数使用适当的宽度 - 没有问题.
但任何人都可以解释为什么错误的根本原因仅在立即窗口中报告?Exception Helper中没有公开任何细节,内部异常为空.知道确切原因不是有益的吗?我认为它会使错误分析更简单,不是吗?
编辑:添加截图; 堆栈跟踪似乎没有暗示任何ADO.NET代码(我没想到).更重要的是,如果我将ret-value参数"声明"保留为SmallInt,但提供一个适当宽度的变量(或如图所示),适应一个int,一切正常!我很确定这与ADO/SQL没有任何关系.
我相信@HansPassant揭示了这里发生的事情的真实本质,我倾向于接受这个作为答案.尽管发现托管代码甚至无法向我提供有关执行状态的准确详细信息(例如,哪个引用实际上为null - 如上所述,或者在此无效转换的情况下),这有点令人失望.
如果您分析 ADO.NET 生成的 SQL,您可能会发现 ADO.NET 尝试将输出参数显式键入为smallint。因此,当 SQL Server 执行您的请求时,它会尝试将存储过程返回的值(int)分配给您告诉它创建为tinyint 的变量。我相信您看到的强制转换异常来自 SQL Server,而不是 .NET。
在命令窗口中,您使用的是 CLR,而不是 TSQL 查询引擎。您的抱怨可能需要针对查询引擎,而不是 .NET。
| 归档时间: |
|
| 查看次数: |
2215 次 |
| 最近记录: |