C#读取oracle的number字段类型

来源:互联网 发布:mac ping ipv6地址 编辑:程序博客网 时间:2024/06/05 21:50

  C#读取Oracle数据有2种方式,一种用.netframework自带的System.Data.OracleClient,一种用Oracle的驱动Oracle.DataAccess需要引用Oracle.DataAccess.dll。

先在oracle数据库中创建表test

create table test

(

topen number(9,4)

)

插入2条记录:

insert into test values(15.2);

insert into test values(15.13);

方式1.采用System.Data.OracleClient

private void OracleClient()
        {
            string connStr = "data source=localhost/orcl;user id=scott;password=tiger;";
            string sql = "SELECT * FROM test“;
            OracleConnection con = new OracleConnection(connStr);
            OracleDataAdapter sda = new OracleDataAdapter();
            OracleCommand cmd = new OracleCommand();
            cmd.Connection = con;
            cmd.CommandTimeout = 300;
            sda.SelectCommand = cmd;
            cmd.CommandText = sql;
            try
            {
                if (con.State == ConnectionState.Closed)
                {
                    con.Open();
                }
                
                DataTable tmpTable = new DataTable();                
                int recordsAffected = sda.Fill(tmpTable);
                string topen1 = tmpTable.Rows[0]["topen"].ToString();
                string topen2 = tmpTable.Rows[1]["topen"].ToString();

            }
            catch (Exception ex)
            {


                throw ex;
            }
            finally
            {
                con.Close();
            }
        }

 topen1, topen2,及tmpTable.Rows[0]["topen"],tmpTable.Rows[1]["topen"]都没有问题

方式2.采用Oracle.DataAccess

private void OracleAccess()
        {
            string connStr = "data source=localhost/orcl;user id=scott;password=tiger;";
            string sql = "SELECT * FROM test";
            Oracle.DataAccess.Client.OracleConnection con = new Oracle.DataAccess.Client.OracleConnection(connStr);
            Oracle.DataAccess.Client.OracleDataAdapter sda = new Oracle.DataAccess.Client.OracleDataAdapter();
            Oracle.DataAccess.Client.OracleCommand cmd = new Oracle.DataAccess.Client.OracleCommand();
            cmd.Connection = con;
            cmd.CommandTimeout = 3600;
            sda.SelectCommand = cmd;
            cmd.CommandText = sql;
            try
            {
                if (con.State == ConnectionState.Closed)
                {
                    con.Open();
                }

                DataTable tmpTable = new DataTable();
                //sda.SafeMapping.Add("TOPEN",typeof(System.String));
                int recordsAffected = sda.Fill(tmpTable);             
                string topen1 = tmpTable.Rows[0]["topen"].ToString();
                string topen2 = tmpTable.Rows[1]["topen"].ToString();

            }
            catch (Exception ex)
            {


                throw ex;
            }
            finally
            {
                con.Close();
            }
        }


 topen2,及tmpTable.Rows[1]["topen"]都没有问题,但tmpTable.Rows[0]["topen"]有问题显示值为15.200000000000001,ToString后topen1又正常了。

如果你是把datatable绑定到datagridview用的,你会在界面上看到这个显示有问题的值。

原因:使用tmpTable.Rows[1]["topen"].GetType()发现这个值是用的是C#中的double类型,double类型我们知道是近似值。

方式2取值正确是因为microsoft把这个值识别为decimal类型。

可惜在网上找不到来自于微软和甲骨文的权威解释。

那么我就此作个总结

结论:oracle提供的.net驱动对于某些数据类型如number的支持不如微软的好用。

解决办法:如果想用oracle提供的.net驱动,对于number类型的解决办法,在方式2的代码中去掉那行注释。

如果有那位有更好的办法或对上述情况有深入的了解,可以回贴补充说明。