2009-08-13 11 views
1

Ich bin heute Morgen von Oracle in ein komisches Verhalten geraten ... Und ich kann nicht verstehen, warum es so von den Dokumenten ausgeht. Es tut mir leid für den langen Beitrag, aber ich möchte sicherstellen, dass ich verstanden werde. Oh, und stellen Sie sicher, den Hinweis am Ende zu lesen, bevor :)Oracles rätselhaftes Verhalten mit NLS_SORT und einem einfachen regexp_like

Ziel der Anfrage zu beantworten ist Reihen mit 1 oder mehreren Kleinbuchstaben zurückzukehren. Aus Gründen des Beispiels wird mein Tisch sein:

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'); 

Mit Hilfe dieser SQL-Anfrage:

select val, 
case when regexp_like (val, '[a-b]') then 'MATCH' else 'NO' end from temp_table; 

Wenn der NLS_SORT Wert der Sitzung BINARY gesetzt, Oracle kehrt:

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

=> Alles gut hier: das einzige Wort mit einem Kleinbuchstaben passt; die anderen nicht.

aber wenn NLS_SORT auf Französisch festgelegt ist, sind die Ergebnisse weniger verständlich:

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

Von dem, was ich ableiten kann, die regexp Matches, wenn es Zeichen A sind.

Meine Frage ist also: Warum würde Oracle [a-z] als 'Zeilen mit Buchstaben, die nicht A sind' verstehen?

Anmerkung 1: Specs: Die Datenbank ist unter Oracle 10G (r2) und die NLS-Parameter der Session sind wie folgt:

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 

Anmerkung 2: Ja, ich konnte REGEXP_LIKE verwenden (val, '[[: lower:]]'). Aber ich habe später davon erfahren, und es erklärt das seltsame Verhalten nicht.

Antwort

3

Zum besseren oder schlechteren wird die von nls_sort definierte Sortierung verwendet, um die [a-z] regexp auszuwerten. Wenn Sie einen einfügen, b, c, A, B und C in temp_table und unter jeder sortieren Einstellung erhalten Sie die folgende erhalten:

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. 

Da die Großbuchstaben sind „verschachtelt“ mit dem unteren Gehäuse Buchstaben in der französischen Fassung wird in der Implementierung von Oracle als wahr bewertet.

+0

Macht total Sinn, danke! – altermativ

Verwandte Themen