传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确

记录一次很少见的Sql异常排查,异常内容:

传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。参数 5 ("@TestValue"): 提供的值不是数据类型 float 的有效实例。请检查源数据中的无效值。例如,小数位数大于精度的数值类型的数据即为无效值。

详细的异常信息如下:

System.Data.SqlClient.SqlException (0x80131904): 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。参数 5 ("@TestValue"): 提供的值不是数据类型 float 的有效实例。请检查源数据中的无效值。例如,小数位数大于精度的数值类型的数据即为无效值。
at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, SqlDataReader ds)
at System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite, String methodName)
at System.Data.SqlClient.SqlCommand.ExecuteNonQuery()

 

乍一看异常信息提示的很明显,@TestValue参数的值不是有效的float类型。

但是前端调用接口时,传参也指定了有效的数值,困惑~

{
   testValue: 10
}

 

经过一顿源码分析,发现原来是由于一些业务逻辑的计算(由于脏数据导致了除0行为),最终导致了@TestValue参数的值变成了NAN,从而导致了上述异常的发生。

 

顺便来个小测试:

Console.WriteLine($"0/0.0d = {0 / 0.0d}");
// 输出:0/0.0d = NaN

Console.WriteLine($"0/0.0f = {0 / 0.0f}");
// 输出:0/0.0f = NaN

int nZero = 0;
//此处需要将除数0声明为变量nZero传入表达式,否则编译不通过
Console.WriteLine($"0/0 = {0 / nZero}");
//引发异常:System.DivideByZeroException:“尝试除以零。”

decimal dZero = 0.0m;
//此处需要将除数0.0m声明为变量dZero传入表达式,否则编译不通过
Console.WriteLine($"0/0.0m = {0 / dZero}");
//引发异常:System.DivideByZeroException:“尝试除以零。”

 

有没有发现猫腻?

  • 0除以浮点类型(float和double)的0 返回的是NAN
  • 0除以十进制类型decimal的0会抛出System.DivideByZeroException异常
  • 0除以整型(有符号和无符号)的0会抛出System.DivideByZeroException异常

 

你可能感兴趣的:(传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确)