#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)