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的代碼中去掉那行註釋。
如果有那位有更好的辦法或對上述情況有深入的瞭解,可以回貼補充說明。