DataAdapter.Fill()在加载较大的十进制值时引发溢出异常

时间:2018-08-07 13:06:11

标签: c# mysql vb.net oracle datatables

我正在尝试从MySQL和Oracle数据库加载较大的十进制值,这会导致异常。我了解到,当它尝试将值转换为.Net的十进制数据类型时,会导致异常,但是从数据库中读取如此巨大的值的方法是什么?

MySQL数据库异常

  

System.Number.ParseDecimal(字符串值,NumberStyles选项,   System.Convert.ToDecimal(字符串值的NumberFormatInfo numfmt)   IFormatProvider提供程序)   MySql.Data.Types.MySqlDecimal.MySql.Data.Types.IMySqlValue.get_Value()   在MySql.Data.MySqlClient.MySqlDataReader.GetValue(Int32 i)在   MySql.Data.MySqlClient.MySqlDataReader.GetValues(Object [] values)在   System.Data.ProviderBase.SchemaMapping.LoadDataRow()在   System.Data.Common.DataAdapter.FillLoadDataRow(SchemaMapping映射)   在System.Data.Common.DataAdapter.FillFromReader(DataSet数据集,   DataTable datatable,String srcTable,DataReaderContainer dataReader,   Int32 startRecord,Int32 maxRecords,DataColumn parentChapterColumn,   对象parentChapterValue)位于   System.Data.Common.DataAdapter.Fill(DataTable [] dataTables,   IDataReader dataReader,Int32 startRecord,Int32 maxRecords)位于   System.Data.Common.DbDataAdapter.FillInternal(DataSet数据集,   DataTable []数据表,Int32 startRecord,Int32 maxRecords,字符串   srcTable,IDbCommand命令,CommandBehavior行为)位于   System.Data.Common.DbDataAdapter.Fill(DataTable [] dataTables,Int32   startRecord,Int32 maxRecords,IDbCommand命令,CommandBehavior   行为)在System.Data.Common.DbDataAdapter.Fill(DataTable   dataTable)

Oracle数据库异常

  

System.OverflowException:算术运算导致   溢出。在Oracle.DataAccess.Types.DecimalConv.GetDecimal(IntPtr   Oracle.DataAccess.Client.OracleDataReader.GetDecimal(Int32)上的numCtx)   i)位于Oracle.DataAccess.Client.OracleDataReader.GetValue(Int32 i)   Oracle.DataAccess.Client.OracleDataReader.GetValues(Object []值)   在System.Data.ProviderBase.SchemaMapping.LoadDataRow()在   System.Data.Common.DataAdapter.FillLoadDataRow(SchemaMapping映射)   在System.Data.Common.DataAdapter.FillFromReader(DataSet数据集,   DataTable datatable,String srcTable,DataReaderContainer dataReader,   Int32 startRecord,Int32 maxRecords,DataColumn parentChapterColumn,   对象parentChapterValue)位于   System.Data.Common.DataAdapter.Fill(DataTable [] dataTables,   IDataReader dataReader,Int32 startRecord,Int32 maxRecords)位于   Oracle.DataAccess.Client.OracleDataAdapter.Fill(DataTable []   dataTables,Int32 startRecord,Int32 maxRecords,IDbCommand命令,   CommandBehavior行为)   System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)

这是我在VB.Net中的示例代码

Using comm = createCommand(strSql, CommandType.Text,60)
   Using Da = _providerFactory.CreateDataAdapter
       Da.MissingSchemaAction = MissingSchemaAction.Add
       Da.SelectCommand = comm
       Da.SelectCommand.CommandTimeout = 60
       Dim dt As New DataTable
       Da.Fill(dt)                  
       Return dt
   End Using
End Using

我要读取的样本值

  

792281625142643375935439503351.000000000000000000000000000012

我发现了其他各种链接,例如this可以解决我的问题,但没有一个适合我。我愿意将值读取为字符串并稍后进行转换。

编辑1:

数据库查询不受我的控制,因此我无法编辑客户端传递的查询。另外,我还使用工厂模式为创建DataAdapter提供了对多个数据库(如MySql,Oracle,DB2,Sqlite,Sqlserver等)的支持,因此编辑查询是不可行的。我的工具使用用户提供的查询来获取数据,并以xml格式提供输出。

编辑2:

我尝试使用 Java 来获取数据,并且 resultset.getString(“ column_name”)可以很好地将数据作为String来获取。 .Net中是否有类似内容?

.p中提供的

DataReader.GetString()无法正常工作。

2 个答案:

答案 0 :(得分:0)

据我所知,.NET Framework本身目前不支持那么大的十进制值。

但是stackoverflow用户Gigo实现了自定义.NET Big Decimal variantSource code)。它不是生产级产品,但适用于大多数情况。

我建议尝试使用他的变体,并将任何问题报告给存储库,以便他们能够修复它们。

答案 1 :(得分:0)

由于该值太大而无法作为.NET Decimal读取,因此您必须在执行MySqlDataReader或使用MySqlDataAdapter之前将其转换为数据库上的字符串。阅读它。

将您的SQL更改为:

SELECT CAST(BigDecimalValue AS CHAR), ... FROM table ...

然后,当您读取此值时,它将是一个包含十进制数字的String。您将必须“将值读取为字符串,然后再进行转换。”