2017-05-30 31 views
0

嘗試使用ODP.NET(ODAC)從Oracle數據庫訪問數據時遇到異常。該代碼是這樣的:嘗試使用ODAC在土耳其語中的列名中檢索列的例外

Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("tr-tr"); 
string s = "SELECT MyString from MyTable"; 
var conn = new OracleConnection(connectString); 
conn.Open(); 
var cmd = new OracleCommand(s, conn); 
var rdr = cmd.ExecuteReader(); 
rdr.Read(); 
object o1 = rdr[0]; 
object o2 = rdr["MYSTRING"]; 
object o3 = rdr["MyString"]; 

O1以及O2的分配工作確定,但O3分配給出了一個例外:

System.IndexOutOfRangeException: Unable to find specified column in result set 
    at Oracle.DataAccess.Client.OracleDataReader.GetOrdinal(String name) 
    at Oracle.DataAccess.Client.OracleDataReader.get_Item(String columnName) 

我充分認識到「土耳其我」的問題。它看起來像我在ODAC中的一個錯誤(它使用當前的文化而不是不變的文化將列名轉換爲大寫),但我還沒有發現其他人報告過類似的問題。

兩個問題:

  1. 這真的是在ODAC的錯誤還是我做錯了什麼?

  2. 如果它是一個錯誤,作爲解決方法,我可以簡單地在檢索命名列時將所有列名轉換爲大寫(使用不變文化)?

+0

我已經反編譯了代碼,我可以看到它在做大寫轉換,不幸的是它使用當前的區域設置,所以從服務器返回的列名是MYSTRING,如果我要求MyString,它實際上是在尋找一個名爲MYSTRİNG的列(大寫字母爲I),它不存在。 – Andy

回答

0

我不認爲這與任何語言設置有關。默認情況下,Oracle中的列名都是大寫。如果你想擁有它區分大小寫,嘗試

string s = "SELECT MyString AS \"MyString\" from MyTable"; 

當然,在這種情況下object o2 = rdr["MYSTRING"];將失敗。

在情況下,它是土耳其語言問題:

Oracle.DataAccess不依賴於當前的.NET區域性設置,它繼承了NLS_LANG值設置。啓動您的應用程序之前,例如

NLS_LANG=TURKISH_TURKEY.AL32UTF8 

正確設置NLS_LANG值可以設置它無論是作爲環境變量或註冊處HKLM\SOFTWARE\Wow6432Node\ORACLE\KEY_%ORACLE_HOME_NAME%\NLS_LANG(在64位Windows 32位應用程序),RESP。 HKLM\SOFTWARE\ORACLE\KEY_%ORACLE_HOME_NAME%\NLS_LANG(對於64位)。

另一個解決辦法是改變它在Oracle會話在執行查詢之前是這樣的:

cmd.CommandText = "ALTER SESSION SET NLS_TERRITORY = 'TURKEY'"; 
cmd.ExecuteNonQuery(); 

或者你可以使用託管驅動程序的ODP.NET ,這不是NLS_LANG敏感。它只有.NET語言環境敏感(但不支持基於線程的全球化),請參閱Data Provider for .NET Developer's Guide

+0

我不是想讓它不區分大小寫,我也不想存儲任何土耳其語數據;我只是試圖通過指定列名從數據庫表中檢索一列。 – Andy

+0

順便說一句關於ODP.NET託管驅動程序的提示 - 我沒有意識到這一點,但肯定會調查這一點。即使它具有相同的錯誤,它也會更容易部署 – Andy

+0

對不起,第一條評論應該已經讀過「我不想讓它區分大小寫」 – Andy