尝试使用ODP.NET(ODAC)从Oracle数据库访问数据时遇到异常。代码如下:
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中的一个错误(它使用当前文化而不是不变文化将列名称转换为大写)但我还没有发现其他人报告类似问题。
两个问题:
这真的是ODAC中的一个错误,还是我做错了什么?
如果是一个bug,作为一种解决方法,我可以在检索命名列时简单地将所有列名转换为大写(使用不变文化)吗?
答案 0 :(得分:0)
我认为这与任何语言设置无关。默认情况下,Oracle中的列名都是大写的。如果您希望区分大小写,请尝试
string s = "SELECT MyString AS \"MyString\" from MyTable";
当然,在这种情况下object o2 = rdr["MYSTRING"];
会失败。
如果土耳其语出现问题:
Oracle.DataAccess
不依赖于当前的.NET文化设置,它继承了NLS_LANG
值的设置。在开始申请之前正确设置NLS_LANG
值,例如
NLS_LANG=TURKISH_TURKEY.AL32UTF8
您可以将其设置为环境变量,也可以将其设置为HKLM\SOFTWARE\Wow6432Node\ORACLE\KEY_%ORACLE_HOME_NAME%\NLS_LANG
中的注册表(对于64位Windows上的32位应用程序),或者。 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