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的代码中去掉那行注释。
如果有那位有更好的办法或对上述情况有深入的了解,可以回贴补充说明。