В C #, как мне обрабатывать типы Oracle Float?Получена ошибка «Арифметическая операция привела к переполнению» - PullRequest
2 голосов
/ 22 июля 2010

Я использую общий подход к получению одной строки из любой таблицы Oracle и отображению ее в виде таблицы данных с использованием приведенного ниже кода.Но, если таблица содержит столбец типа с плавающей запятой и значение имеет большое количество десятичных знаков, я получаю «Арифметическая операция, приведшая к переполнению» в строке: 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 ​​(Object [] values)

Итак, я могу понять, почему это вызывает ошибку (предполагается, что выполняется десятичное преобразование);но как мне обойти это?

Я попытался явно установить тип столбца перед загрузкой данных с помощью:

dgvStagingTable.Columns ["TR_THROUGHPUT_TIME_NO"]. ValueType = typeof (string);

и несколько других типов, но ничто не имело никакого значения.

Любая помощь приветствуется.

1 Ответ

2 голосов
/ 22 июля 2010

Сначала я предложил использовать 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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...