两个小数字段中的第一个字段在获取时引起异常。

问题描述 投票:0回答:1

我有一个用C#编写的应用程序,它使用了 OdbcConnection, OdbcCommandOdbcDataReader. 查询是在Linux系统上运行的Informix SE数据库中进行的。

在查询中,在序数位置27和28(索引26和27),我试图获取每个水表记录中存储的经纬度。

下面是12K+账户中第一个账户的latlong,当使用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。只选择latlong十进制(15,10)的值,这些值就能完美地获取。

这是我们Linux服务器上的Informix版本,它运行的是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。是geo_lat的GetDecimal(26)抛出了一个无效的投递异常。请注意 folio (选择在 geo_lat 之前)是个 小企业,我可以用这个方法只读出整数部分 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 ";                
c# odbc informix decimalformat
1个回答
1
投票

我使用.NET Framework 4.7来编译下面的程序。

我使用CSDKODBC 4.50.FC3版本(Windows 64-bit)在Informix数据库中尝试了下面的简单程序,它工作得很完美。

你能不能也分享一下你使用的Informix CSDKODBC的版本("esql -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
投票

你能分享System.Data.dllSystem.Data.Odbc.dll的版本吗(根据你使用的Framework版本,System.Data.Odbc.dll可能是System.Data.dll本身的一部分)?

另外,你可以试试我分享的程序吗?这是一个自足的测试案例,这将确认问题,因为我们在各自的环境中尝试完全相同的测试案例。

© www.soinside.com 2019 - 2024. All rights reserved.