C # OracleDataReader.Get???(oracle AVG()) Исключение InvalidCastException

#c# #oracle #.net

#c# #Oracle #.net

Вопрос:

Я работаю на C # с базой данных oracle, и у меня возникают некоторые проблемы с исключением InvalidCastException при попытке извлечь данные из OracleDataReader.

Проблема заключается в типе функции AVG(). Это запрос:

 SELECT AVG(MBAR) mbavg, AVG(ML_MIN) mlavg, RSZ FROM (SELECT * FROM ( SELECT ID, RSZ rsz2 FROM SZIVARGASMERO ORDER BY ID DESC ) WHERE ROWNUM=1 ) a, SZIVARGASMERO WHERE RSZ=a.RSZ2 GROUP BY RSZ;
  

Таблица выглядит следующим образом:

 CREATE TABLE SZIVARGASMERO
(
  ID          NUMBER                            NOT NULL,
  RSZ         VARCHAR2(1000 BYTE),
  CIKKSZ      VARCHAR2(500 BYTE),
  DATE_G      DATE,
  DEV_ID      INTEGER,
  PROG        INTEGER,
  RES         VARCHAR2(50 BYTE),
  REG1        INTEGER,
  MBAR        FLOAT(126),
  FE          VARCHAR2(50 BYTE),
  REG2        INTEGER,
  ML_MIN      FLOAT(126),
  TIMESTAMPA  DATE,
  ERROR       INTEGER
)
  

Я пытался

 double mbavg=reader.GetDouble(reader.GetOrdinal("mbavg"));
float mbavg=reader.GetFloat(reader.GetOrdinal("mbavg"));
  

А также

 string mbavg=reader.GetString(reader.GetOrdinal("mbavg"));
  

И я попытался проанализировать double с помощью CultureInvariant и System.Конверсия.TOXX тоже, но ни один из них не работает.

 using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
using System.Threading;
//using MySql.Data.MySqlClient;
using System.Globalization;
using Oracle.DataAccess.Client;
using Oracle.DataAccess.Types;
....

public const string oradb ="....";
public OracleConnection conn = new OracleConnection(oradb);
...
OracleCommand cmd = new OracleCommand();
            conn.Open();
            try
            {
                cmd.Connection = conn;
                cmd.CommandText = "SELECT AVG(MBAR) mbavg, AVG(ML_MIN) mlavg, RSZ FROM (SELECT * FROM ( SELECT ID, RSZ rsz2 FROM SZIVARGASMERO ORDER BY ID DESC ) WHERE ROWNUM=1 ) a, SZIVARGASMERO WHERE RSZ=a.RSZ2 GROUP BY RSZ";
                cmd.CommandType = CommandType.Text;
                OracleDataReader dr = cmd.ExecuteReader();
                //cmd.ExecuteNonQuery();
                while (dr.Read())
                {
                    if (dr.HasRows)
                    {

                       // double mbavg = dr.GetDouble(0);
                        double mlavg = dr.GetDouble(dr.GetOrdinal("mlavg"));
                        string last_rsz = dr.GetString(dr.GetOrdinal("RSZ"));
                       // mbaravg.Text = System.Convert.ToString(mbavg)   " mbar";
                        mlavg_lb.Text = System.Convert.ToString(mlavg)   " ml/min";
                        last_rsz_lb.Text = last_rsz;
                    }
                }
                dr.Dispose();
                dr.Close();

            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                if (conn.State == ConnectionState.Open)
                {
                    oracle_lb.Text = "OK";
                    ora_lbl_2.Text = "Oracle: OK!";
                    ora_lbl_2.ForeColor = Color.DarkGreen;
                }
                else
                {
                    MessageBox.Show("Nincs adatbáziskapcsolat!");
                }
  

Кто мог бы это решить? Пожалуйста, помогите мне. Большое вам спасибо 🙂

Редактировать:

 cmd.CommandText = "SELECT TRUNC(AVG(MBAR),6) mbavg, TRUNC(AVG(ML_MIN),6) mlavg, RSZ FROM (SELECT * FROM ( SELECT ID, RSZ rsz2 FROM SZIVARGASMERO ORDER BY ID DESC ) WHERE ROWNUM=1 ) a, SZIVARGASMERO WHERE RSZ=a.RSZ2 GROUP BY RSZ";

decimal mbavg_d=dr.GetDecimal(GetOrdinal("mbavg"));

double mbavg=(double)mbavg_d
  

Комментарии:

1. Можете ли вы попытаться определить, к какому типу данных относится поле, используя dr.GetFieldType(dr.GetOrdinal("mlavg")) ? Имеет ли вывод SQL значение null для какого-либо из полей, по которым вы выполняете усреднение?

2. Каково значение reader.GetOrdinal("mbavg") именно при его дебюте?

3. Я не знаю, как правильно использовать GetFieldType. Я пробовал это, но если я отлажу его, я не смогу увидеть его значение. Если я выполняю запрос в Toad, значение mbavg равно 461,868421052632 (возможно, проблема в десятичной ЗАПЯТОЙ), но я также попробовал Double . Разбор…

4. Значение GetOrdinal равно 0, я также перепробовал все методы без GetOrdinal и с использованием 0

5. Вы пробовали .GetValue(dr.getordinal(…))? Должен возвращаться как объект, и отладчик может затем сообщить вам, каким типом он видит objdct? После этого должно сработать преобразование.toxxx(…) вокруг объекта.

Ответ №1:

Это проблема с типом данных Oracle «NUMBER». Оно тесно связано с десятичным числом, но может содержать гораздо больше цифр. Я рекомендую усечь результат AVG, например

  TRUNC(AVG(MBAR), 6)