首页 > 解决方案 > DataAdapter.Fill() 在加载大十进制值时抛出溢出异常

问题描述

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

MySQL 数据库的异常

System.Number.ParseDecimal(String value, NumberStyles options, NumberFormatInfo numfmt) at System.Convert.ToDecimal(String value, IFormatProvider provider) at 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 数据表,String srcTable,DataReaderContainer dataReader,Int32 startRecord,Int32 maxRecords,DataColumn parentChapterColumn,Object parentChapterValue)在 System.Data.Common.DataAdapter.Fill( DataTable[] 数据表,IDataReader 数据读取器,Int32 startRecord, Int32 maxRecords) 在 System.Data.Common.DbDataAdapter.FillInternal(DataSet dataset, DataTable[] datatables, Int32 startRecord, Int32 maxRecords, String srcTable, IDbCommand command, CommandBehavior behavior) at System.Data.Common.DbDataAdapter.Fill (DataTable[] dataTables,Int32 startRecord,Int32 maxRecords,IDbCommand 命令,CommandBehavior 行为)在 System.Data.Common.DbDataAdapter.Fill(DataTable dataTable)DbDataAdapter.Fill(DataTable 数据表)DbDataAdapter.Fill(DataTable 数据表)

Oracle 数据库异常

System.OverflowException:算术运算导致溢出。在 Oracle.DataAccess.Types.DecimalConv.GetDecimal(IntPtr numCtx) 在 Oracle.DataAccess.Client.OracleDataReader.GetDecimal(Int32 i) 在 Oracle.DataAccess.Client.OracleDataReader.GetValue(Int32 i) 在 Oracle.DataAccess.Client.OracleDataReader .GetValues(Object[] values) at System.Data.ProviderBase.SchemaMapping.LoadDataRow() at System.Data.Common.DataAdapter.FillLoadDataRow(SchemaMapping mapping) at System.Data.Common.DataAdapter.FillFromReader(DataSet dataset, DataTable datatable , String srcTable, DataReaderContainer dataReader, Int32 startRecord, Int32 maxRecords, DataColumn parentChapterColumn, Object parentChapterValue) at System.Data.Common.DataAdapter.Fill(DataTable[] dataTables, IDataReader dataReader, Int32 startRecord, Int32 maxRecords) 在 Oracle。

这是我在 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

我为我的问题找到了各种其他链接,例如这个链接,但没有一个对我有用。我愿意将值读取为字符串并稍后进行转换。

编辑1:

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

编辑2:

我尝试使用Java来获取数据,resultset.getString("column_name")可以很好地以字符串的形式获取数据。我们在.Net中有类似的东西吗?

.Net 中提供的 DataReader.GetString() 不起作用。

标签: c#mysqlvb.netoracledatatables

解决方案


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

将您的 SQL 更改为:

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

然后,当您读取此值时,它将是一个String包含十进制数字的值。您将不得不“将值读取为字符串并稍后进行转换。”</p>


推荐阅读