我在 Oracle 11g 数据库中有一个表“审计”。该表有一列“Account_Name”。“Audit”.“Account_name”列包含以下数据:“Guest”、“feeder_1”、“feeder_2”、“feeder_3”等。
我在“Audit.Account_Name”列上创建了以下索引。
CREATE INDEX AUDIT_IX9_CI ON AUDIT (NLSSORT("ACCOUNT_NAME",'nls_sort=''BINARY_CI'''));
从 JDBC 代码中,我首先执行以下语句,然后执行实际查询以从“审计”表中获取数据。
connection.prepareStatement("ALTER SESSION SET NLS_COMP=LINGUISTIC"); //line1
connection.prepareStatement("ALTER SESSION SET NLS_SORT=BINARY_CI"); // line2
//这是执行以获取数据的代码
connection.prepareStatement("select account_name from audit where (ACCOUNT_NAME like 'f%' ) ");//line3
rs = pst.executeQuery();//line4
while(rs.next()){
String accountName = rs.getString("account_name");
System.out.println("account name "+accountName);
}
上面的查询从表中获取所有数据,包括像“Guest”这样的值。我除了查询应该只获取 Account_name 以“f”开头的行,但看起来像 NLS_SORT 和 NLS_COMP 正在获取不正确的数据。
我发现如果我评论“line2”,它会正确获取数据。谁能建议为什么这些选项不能正常工作。
我在同一个连接对象上执行了来自 JDBC 代码的查询。
select PARAMETER, value from nls_session_parameters
NLS_LANGUAGE = AMERICAN
NLS_TERRITORY = AMERICA
NLS_CURRENCY = $
NLS_ISO_CURRENCY = AMERICA
NLS_NUMERIC_CHARACTERS = .,
NLS_CALENDAR = GREGORIAN
NLS_DATE_FORMAT = DD-MON-RR
NLS_DATE_LANGUAGE = AMERICAN
NLS_SORT = BINARY_CI
NLS_TIME_FORMAT = HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT = DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT = HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT = DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY = $
NLS_COMP = LINGUISTIC
NLS_LENGTH_SEMANTICS = BYTEs
NLS_NCHAR_CONV_EXCP = FALSE
这个问题是在生产环境中提出的。所以早些时候我已经使用 JDBC 编写了一个独立的 Java 代码来检查我是否遇到了与生产中相同的问题。
我现在编写了一个 Oracle 程序,在程序中首先设置 NLS_COMP 和 NLS_SORT 参数,然后执行搜索查询(此处使用 CURSOR),然后重新设置 NLS_SORT=BINARY。结果是一样的,我遇到了同样的问题。
解释计划 从审计中选择 account_name 其中 account_name like 'f%' 计划哈希值:1078245361 -------------------------------------------------- -------------------------------- | 身份证 | 操作 | 姓名 | 行 | 字节 | 成本 (%CPU)| 时间 | -------------------------------------------------- -------------------------------- | 0 | 选择声明 | | 10 | 2580 | 1 (0)| 00:00:01 | |* 1 | 索引范围扫描| 审计_IX9 | 10 | 2580 | 1 (0)| 00:00:01 | -------------------------------------------------- -------------------------------- 谓词信息(由操作 id 标识): -------------------------------------------------- - 1 - 访问("ACCOUNT_NAME" LIKE U'f%') filter("ACCOUNT_NAME" LIKE U'f%') 笔记 ----- - 用于此语句的动态采样 (level=2)
执行以下查询后,我得到字符集为“WE8MSWIN1252”;
从 nls_database_parameters 中选择值到 char_set 中,其中 parameter = 'NLS_CHARACTERSET';