2009-08-13 39 views
1

我今天早上遇到了一个从Oracle怪异的行为......我不明白为什么它的行为从文档这种方式。我在很长的帖子对不起,但我想确保我的理解。 噢,并确保在年底回答:)Oracle的令人费解的行为与NLS_SORT和简单REGEXP_LIKE

请求的目标之前阅读说明是与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设置为法语,结果不太理解:

00A00 NO 
00000 NO 
BC000 MATCH 
ABC00 MATCH 
AAAAA NO 
abc00 MATCH 

从我可以推断,当有一个比其他人物正则表达式匹配。

所以我的问题是:为什么甲骨文将[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:]]')。但是我发现了这事以后,它不解释怪异的行为。

回答

3

无论好坏,nls_sort定义的排序顺序都用于评估[a-z]正则表达式。如果插入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的实施中,法语环境中的字母评估为真。

+0

总体感觉,谢谢! – altermativ 2009-08-13 16:31:34