我今天早上从Oracle遇到了一个奇怪的行为......我无法理解为什么它从文档中以这种方式起作用。对于长篇文章我很抱歉,但我想确保我理解。 哦,并确保在回答之前阅读结尾处的注释:)
请求的目标是返回包含1个或多个小写字符的行。为了示例,我的表将是:
CREATE TABLE "TEMP_TABLE"
( "VAL" VARCHAR2(4000 BYTE) );
Insert into TEMP_TABLE (VAL) values ('00A00');
Insert into TEMP_TABLE (VAL) values ('00000');
Insert into TEMP_TABLE (VAL) values ('BC000');
Insert into TEMP_TABLE (VAL) values ('ABC00');
Insert into TEMP_TABLE (VAL) values ('AAAAA');
Insert into TEMP_TABLE (VAL) values ('abc00');
使用此SQL请求:
select val,
case when regexp_like (val, '[a-b]') then 'MATCH' else 'NO' end from temp_table;
如果会话的 NLS_SORT 值设置为BINARY,则oracle返回:
00A00 NO
00000 NO
BC000 NO
ABC00 NO
AAAAA NO
abc00 MATCH
=>这里一切都很好:唯一包含小写字母的单词匹配;其他人没有。
但是如果 NLS_SORT 设置为FRENCH,结果就不那么容易理解了:
00A00 NO
00000 NO
BC000 MATCH
ABC00 MATCH
AAAAA NO
abc00 MATCH
根据我的推断,当有字符而不是A 时,正则表达式匹配。
所以我的问题是:为什么Oracle会将[a-z]理解为'字母不是A'的行?
注1:规格: 该数据库位于Oracle 10G(r2)下,会话的NLS参数如下:
NLS_CALENDAR GREGORIAN
NLS_COMP BINARY
NLS_CURRENCY ¿
NLS_DATE_FORMAT DD/MM/RR HH24:MI
NLS_DATE_LANGUAGE FRENCH
NLS_DUAL_CURRENCY ¿
NLS_ISO_CURRENCY FRANCE
NLS_LANGUAGE FRENCH
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
NLS_NUMERIC_CHARACTERS ,
NLS_SORT FRENCH_M
NLS_TERRITORY FRANCE
NLS_TIME_FORMAT HH24:MI:SSXFF
NLS_TIMESTAMP_FORMAT DD/MM/RR HH24:MI:SSXFF
NLS_TIMESTAMP_TZ_FORMAT DD/MM/RR HH24:MI:SSXFF TZR
NLS_TIME_TZ_FORMAT HH24:MI:SSXFF TZR
注2:是的,我可以使用regexp_like(val,'[[:lower:]]')。但是我后来发现了这一点,并没有解释这种奇怪的行为。
答案 0 :(得分:3)
无论好坏,nls_sort定义的排序顺序用于评估[a-z] regexp。如果您将a,b,c,A,B和C插入temp_table并在每个设置下对其进行排序,您将获得以下内容:
SQL> alter session set nls_sort=BINARY;
Session altered.
SQL> select val,
2 case when regexp_like (val, '[a-z]') then 'MATCH' else 'NO' end m
3 from temp_table order by val;
VAL M
------------------------- -------------------------
A NO
B NO
C NO
a MATCH
b MATCH
c MATCH
6 rows selected.
SQL> alter session set nls_sort=FRENCH;
Session altered.
SQL> select val,
2 case when regexp_like (val, '[a-z]') then 'MATCH' else 'NO' end m
3 from temp_table order by val;
VAL M
------------------------- -------------------------
A NO
a MATCH
B MATCH
b MATCH
C MATCH
c MATCH
6 rows selected.
由于大写字母与法语设置中的小写字母“交错”,因此在Oracle的实现中评估为true。