我正在使用一种通用方法从任何 Oracle 表接收单行并将其显示在数据 GridView 中,使用以下代码。但是,如果该表包含一个浮点类型的列并且该值具有大量小数位,我会在该行得到“算术运算导致溢出”:MyReader.GetValues(objCells);
oCmd.CommandText = "OTCMIADM.OTCMI_GUI.GET_ROW";
oCmd.CommandType = CommandType.StoredProcedure;
oCmd.Parameters.Add("PI_TABLE_NAME", OracleDbType.Varchar2, 40).Value = cmbStagingTables.SelectedItem;
oCmd.Parameters.Add("PI_ROWID", OracleDbType.Varchar2, 40).Value = txtRowID.Text;
oCmd.Parameters.Add(new OracleParameter("PIO_CURSOR", OracleDbType.RefCursor)).Direction = ParameterDirection.Output;
oCmd.ExecuteNonQuery();
// clear the datagrid in preperation for loading
dgvStagingTable.Columns.Clear();
dgvStagingTable.Rows.Clear();
using (OracleDataReader MyReader = oCmd.ExecuteReader())
{
int ColumnCount = MyReader.FieldCount;
// add the column headers
DataGridViewColumn[] columns = new DataGridViewColumn[ColumnCount];
for (int i = 0; i < columns.Length; ++i)
{
DataGridViewColumn column = new DataGridViewTextBoxColumn();
column.FillWeight = 1;
column.HeaderText = MyReader.GetName(i);
column.Name = MyReader.GetName(i);
columns[i] = column;
}
dgvStagingTable.Columns.AddRange(columns);
// get the data and add the row
while (MyReader.Read())
{
//get all row values into an array
object[] objCells = new object[ColumnCount];
MyReader.GetValues(objCells);
//add array as a row to grid
dgvStagingTable.Rows.Add(objCells);
}
}
堆栈跟踪显示: 在 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(对象 [] 值)
所以我可以明白为什么它会导致错误(假设是十进制转换);但是我该如何解决这个问题呢?
我尝试在加载数据之前明确设置列的类型:
dgvStagingTable.Columns["TR_THROUGHPUT_TIME_NO"].ValueType = typeof(string);
和其他几种类型,但没有任何区别。
感谢任何帮助。
最佳答案
我最初建议使用 OracleDbTypeEx ( http://download.oracle.com/docs/html/E15167_01/OracleParameterClass.htm#CHDJHDGE ) 为您解决这个问题,这是错误的,所以这是一个新建议。
所以我做了什么:
Create Table Testdecimalteable(
Acol number(10) ,
DecCol NUMBER(38,38)
);
/
Insert Into Testdecimalteable
Select level,Level/(power(2,level))
From Dual
Connect By Level < 100 ;
/
Create or replace Procedure Testprocdecimal(Crs OUT Sys_Refcursor)
AS
Begin
Open Crs For
Select *
FROM Testdecimalteable ;
END Testprocdecimal ;
现在这将获得一些已知超出 .net 的数据。
然后是 .net 端:
OracleConnection _conn = new OracleConnection("" );
_conn.Open();
OracleCommand oCmd = new OracleCommand();
oCmd.CommandText = "Testprocdecimal";
oCmd.CommandType = CommandType.StoredProcedure;
oCmd.Connection = _conn;
OracleParameter crs = new OracleParameter();
crs.OracleDbType = OracleDbType.RefCursor ;
crs.Direction = ParameterDirection.Output;
crs.ParameterName = "crs";
oCmd.Parameters.Add(crs);
using (OracleDataReader MyReader = oCmd.ExecuteReader())
{
int ColumnCount = MyReader.FieldCount;
// get the data and add the row
while (MyReader.Read())
{
//MyReader.GetOracleValue(1).ToString()
Console.WriteLine(string.Format("{0}/{1}", MyReader.GetValue(0),MyReader.GetOracleValue(1).ToString() ));
}
}
这会将所有内容都转换为字符串,但它会起作用。
http://download-east.oracle.com/docs/html/A96160_01/features.htm#1048038
我刚刚再次查看了您的初始查询,您调用了两次查询:
oCmd.ExecuteNonQuery();
...
using (OracleDataReader MyReader = oCmd.ExecuteReader())
您不需要 ExecuteNonQuery; ExecuteReader 执行 sp
关于c# - 在 C# 中,如何处理 Oracle Float 类型?接收错误 "Arithmetic operation resulted in an overflow",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3307551/