尝试使用' i'检索列的例外情况在土耳其语中使用ODAC的列名称

时间:2017-05-30 11:15:44

标签: oracle localization odp.net odac turkish

尝试使用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中的一个错误(它使用当前文化而不是不变文化将列名称转换为大写)但我还没有发现其他人报告类似问题。

两个问题:

  1. 这真的是ODAC中的一个错误,还是我做错了什么?

  2. 如果是一个bug,作为一种解决方法,我可以在检索命名列时简单地将所有列名转换为大写(使用不变文化)吗?

1 个答案:

答案 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