2013-12-10 19 views
2

我使用OdbcDataReader連接到Oracle數據庫。在那裏我有一個表格,其字段被聲明爲NUMBER(8,2)。我插入了一行值爲'8.23'的行。它在SqlDeveloper中使用SELECT * FROM <table>時正確顯示。連接到Oracle數據源時小數點被OdbcDataReader剝離

但是,當使用OdbcDataReader.GetDecimal()從.NET通過ODBC訪問此字段時,我得到一個包含'823'的Decimal。爲什麼是這樣,我如何得到正確的價值?

編輯:

如果我改用OracleConnection/OracleCommand一切正常。

事實也證明,如果我在我的ODBC驅動程序配置中將「使用Oracle NLS設置」中的「數值設置」更改爲「使用美國設置」,小數點也會正確返回。這裏究竟發生了什麼?

基本上我用下面的代碼:

using (OdbcCommand command = new OdbcCommand("SELECT * FROM TEST", connection)) 
{ 
    using (DbDataReader reader = command.ExecuteReader()) 
    { 
     while (reader.Read()) 
     { 
     Console.WriteLine(reader.GetValue(0)); 
     } 
    } 
} 

這個打印:

823 
823 

但在Oracle SQL Developer中恢復運行SELECT * FROM TEST

FLDNUM82  
---------- 
    8.23  
    8.23 

和運行desc TEST回報:

Name  Null Type   
-------- ---- ----------- 
FLDNUM82  NUMBER(8,2) 

回答

3

經過一番調查來看,在OdbcDataReadersource code我發現,從內部的ODBC數據源檢索類型十進制值時,十進制,它實際上得到它從ODBC提供一個字符串,然後嘗試解析它使用不變區域性小數,在上面的鏈接中找到的批示指出:

// internal GetDecimal 
// ------------------- 
// Get Value of type SQL_DECIMAL or SQL_NUMERIC 
// Due to provider incompatibilities with SQL_DECIMAL or SQL_NUMERIC types we always read the value 
// as SQL_C_WCHAR and convert it back to the Decimal data type 

這意味着,如果該數據提供商發送字符串小數點格式不是由不變文化指定的格式,轉換將失敗,或者更糟糕的是,會產生不正確的結果。在我的情況下,小數點可能作爲逗號字符發回,這在美國文化中是千位分隔符,這意味着在撥打Decimal.TryParse時被忽略。

我不確定OdbcDataReader的作者選擇的解決方案在這裏是否最好,但是我可能會遇到問題,但我不知道。不幸的是,除了遠離ODBC之外,似乎並沒有解決這個問題的好辦法。

0

讀它作爲一個字符串,並將其轉換使用Decimal.TryParse

+0

'reader.GetString(0 )拋出一個異常,因爲這個值的類型是「Decimal」而不是「String」。此外,我實際上並不知道字段的類型,所以我需要使用'GetValue'。 – DeCaf

+0

你可以使用GetVaue.ToString嗎? – CloudyMarble

+0

是的,並返回'823',即沒有小數點。 (更新了一些更詳細的問題) – DeCaf

0

我在Oracle數據庫11gR2上遇到了與Oracle ODBC Driver類似的問題。在ODBC連接設置中將NUM參數設置爲US解決了我的問題。

NUM可能的值有:

  • NLS:使用Oracle NLS設置
  • MS:使用Windows區域設置
  • US:使用美國設置