Первое из двух десятичных полей вызывает исключение при получении - PullRequest
1 голос
/ 23 апреля 2020

У меня есть приложение, написанное на C#, которое использует OdbcConnection , OdbcCommand и OdbcDataReader . Запрос выполняется к базе данных Informix SE, работающей в системе Linux.

В запросе, в порядковых позициях 27 и 28 (индексы 26 и 27), я пытаюсь получить широту и долготу, хранящиеся в каждая запись счетчика воды.

Здесь приведены значения широты / долготы для первой из учетных записей 12K +, для которых первое значение завершается неудачно с недопустимым исключением приведения при чтении с помощью dbReader.GetDecimal (

     geo_lat          geo_lon

42.4236953219 -71.1752100161

Первое поле, которое нужно получить, - это GetDecimal (26), которое выдает недопустимое исключение приведения.

//  Type x = dbReader.GetFieldType(iReadIdx); after
//  testing, it's found to be a decimal.

decimal x = dbReader.GetDecimal(iReadIdx);
retStr = x.ToString();

Обратите внимание, что закомментированный код был запущен, чтобы определить, что индекс 26 действительно десятичная дробь. Я подумал о том, были ли ординалы неправильными. Они не были.

Единственное, что я могу видеть, это то, что широта - это положительное число, а долгота - отрицательное число.

Если мне нужно, я могу составить временную таблицу, чтобы отобразить строковую версию широты, которая в любом случае мне нужна, широта в строке.

Буду признателен за любые идеи о дальнейшей отладке этой проблемы.

Ответы на комментарии:

Я попробовал следующее, которое выдает исключение.

decimal x = decimal.Parse(dbReader.GetString(iReadIdx));

Но это не так, но он также не считывает полное десятичное значение.

decimal x = decimal.Parse(dbReader.GetInt32(iReadIdx).ToString());
retStr = x.ToString();
break;

Я бы понял, если отрицательное значение не было получено правильно, но не положительное значение.

Однако, второй вызов не может быть прочитан как строка. Я должен придумать немного клуджа. Ответы на недавно заданные вопросы:

Мой обходной путь - написать отдельный запрос, используя тот же OdbcConnection, что и основной запрос. Выбирая только значения десятичного и длинного лат (15,10), они выбираются идеально.

Это версия Informix на нашем Linux сервере, на котором работает SE, и мало что меняется для Informix SE .

[ics@steamboy ics_client]$ esql -V
IBM Informix CSDK Version 3.00, IBM Informix-ESQL Version 3.00.UC3DE
Software Serial Number AAA#B000000
[ics@steamboy ics_client]$ 

Вот основной выбор, содержащий поля geo_lat и geo_lon. Это GetDecimal (26) для geo_lat, который генерирует недопустимое исключение приведения. Обратите внимание, что фолио (выбранное до geo_lat) представляет собой smallint , и я мог прочитать только целую часть числа, используя GetInt32 (26) .

string meterQ       =   
"select m.acct_no, "        + //1
"       m.suffix,  "        + //2
"       m.reg_no,  "        + //3
"       w.service, "        + //4
"       m.property_type, "  + //5
"       w.mtr_addr_no,  "   + //6
"       w.mtr_addr_str, "   + //7
"       w.mtr_addr_apt, "   + //8
"       w.owner_city, "     + //9
"       w.owner_state, "    + //10
"       w.owner_zip, "      + //11
"       w.owner_name_1, "   + //12
"       w.owner_name_2, "   + //13
"       w.owner_addr_1, "   + //14
"       w.owner_addr_2, "   + //15
"       w.re_acct,       "  + //16
"       m.meter_type,   "   + //17
"       m.meter_num,    "   + //18
"       m.date_installed, " + //19
"       m.numdigits,    "   + //20
"       w.billed_or_not, "  + //21
"       m.meter_size,   "   + //22
"       m.arb_no, "         + //23
"       m.read_instr, "     + //24
"       m.book, "           + //25
"       m.folio, "          + //26
"       m.geo_lat, "        + //27
"       m.geo_lon, "        + //28 
// cmn 4/24/2020 lat Lon fetched by separate query.
"       m.devicetype, "     + //29
"       m.channel,      "   + //30
"       w.same_re_addr "    + //31
"from   water w ,  meter m " +
"where  w.acct_no = m.acct_no " +
"and    m.last_update >= '" + cutoffDateP + "' " +
"and        m.meter_type != 'FS' "       +
"and        w.last_update is not null   "  +
"order by m.acct_no asc, m.suffix asc ";                

Ответы [ 2 ]

1 голос
/ 24 апреля 2020

Я использую. NET Framework 4.7 для компиляции приведенной ниже программы.

Ниже я попробовал простую программу с базой данных Informix, используя CSDK / ODB C версия 4.50.FC3 (Windows 64-битная ) и работает отлично.

Не могли бы вы также поделиться используемой версией Informix CSDK / ODB C (вывод "e sql -V")?

Вывод приведенной ниже программы следующим образом:

 **** Starting of Decimal Testcase ****
 **** Connected ****
create temp table mytable (intcol int, deccol1 decimal(20,10), deccol2 decimal(20,10));
 Table mytable created
insert into mytable values(1,'42.4236953219', '-71.1752100161');
 INSERT 1 rows
select * from mytable;
intcol = 1
deccol1 = 42.4236953219
deccol2 = -71.1752100161
 **** End of Decimal Testcase ****

Program:
--------
>using System;
>using System.Data;
>using System.Data.Odbc;
>using System.Text;
>
>public class OdbcDecimal
>{
>    static void Main(string[] args) 
>    {
>        int insrow = 0;
>        try 
>        {
>            string connectionString = "DSN=InformixDSN";
>            
>            try 
>            {
>                Console.WriteLine(" **** Starting of Decimal Testcase ****");
>                using (OdbcConnection conn0 = new OdbcConnection(connectionString))
>                {
>                    conn0.Open();
>                    Console.WriteLine(" **** Connected ****");
>                    using (OdbcCommand cmd0 = conn0.CreateCommand())
>                    {
>                        try
>                        {
>                            cmd0.CommandText = "drop table mytable;";
>                            //Console.WriteLine(cmd0.CommandText);
>                            cmd0.ExecuteNonQuery();
>                            //Console.WriteLine(" Table mytable dropped");
>                        }
>                        catch { }
>
>                        cmd0.CommandText = "create table mytable (intcol int, deccol1 >decimal(20,10), deccol2 decimal(20,10));";
>                        Console.WriteLine(cmd0.CommandText);
>                        cmd0.ExecuteNonQuery();
>                        Console.WriteLine(" Table mytable created");
>                        
>                        cmd0.CommandText = "insert into mytable values(1,'42.4236953219', >'-71.1752100161');";
>                        Console.WriteLine(cmd0.CommandText);
>                        insrow = cmd0.ExecuteNonQuery();
>                        Console.WriteLine(" INSERT " + insrow + " rows");
>                        
>                        cmd0.CommandText = "select * from mytable;";
>                        Console.WriteLine(cmd0.CommandText);
>
>                        OdbcDataReader dr = null;
>                        Int32 vid = 0;
>                        decimal x;
>                        decimal y;
>                        
>                        dr = cmd0.ExecuteReader();
>                        while (dr.Read())
>                        {
>                            try
>                            {
>                                if (!dr.IsDBNull(0))
>                                {
>                                    vid = dr.GetInt32(0);
>                                    Console.WriteLine("intcol = " + vid + " ");
>                                }
>                                else
>                                {
>                                    Console.WriteLine("intcol = null ");
>                                }
>
>                                if (!dr.IsDBNull(1))
>                                {
>                                    x = dr.GetDecimal(1);
>                                    Console.WriteLine("deccol1 = " + x.ToString() + " ");
>                                }
>                                else
>                                {
>                                    Console.WriteLine("deccol1 = null  ");
>                                }
>
>                                if (!dr.IsDBNull(2))
>                                {
>                                    y = dr.GetDecimal(2);
>                                    Console.WriteLine("deccol2 = " + y.ToString() + " ");
>                                }
>                                else
>                                {
>                                    Console.WriteLine("deccol2 = null ");
>                                }
>                            }
>                            catch (OverflowException exc)                      
>                            {                                                  
>                                Console.WriteLine(exc.Message);
>                            }
>                        }
>                        dr.Close();
>                          
>                    }
>                }         
>             } 
>             catch (OdbcException ioe) 
>             { 
>                Console.WriteLine(ioe.Message);
>               Console.WriteLine(ioe.StackTrace);
>             } 
>        }
>        catch (Exception ex)
>        {
>            Console.WriteLine(ex.Message);
>            Console.WriteLine(ex.StackTrace);
>        }
>        Console.WriteLine(" **** End of Decimal Testcase ****");
>    } 
>}
0 голосов
/ 25 апреля 2020

Не могли бы вы поделиться версией System.Data.dll / System.Data.Odb c .dll (в зависимости от того, какую версию Framework вы используете, System.Data.Odb c .dll может быть частью системы .Data.dll сама)?

Кроме того, не могли бы вы попробовать программу, которой я поделился? Это самодостаточный тестовый пример, это подтвердит проблему, поскольку мы пробуем точно такой же тестовый пример в наших соответствующих средах.

...