Oracle
 sql >> Database >  >> RDS >> Oracle

L'espressione regolare Oracle con un trattino non dà lo stesso risultato su Windows come su Unix

Come ha affermato Avinash Raj nei commenti, il trattino nel modello di espressione regolare viene interpretato come un intervallo. Il comportamento sembra dipendere dall'algoritmo di ordinamento utilizzato dai due client, basato sulla variabile di ambiente NLS_LANG, che influenza il valore NLS_SORT.

Con NLS_LANG=ENGLISH_UNITED KINGDOM.WE8ISO8859P1 :

SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-={}|;.:<>?,./]', ' ') as REG from dual;

REG
------------
TEST      V

SQL> select value from nls_session_parameters where parameter = 'NLS_SORT';

VALUE
----------
BINARY

Uscire su un ramo mentre il tuo profilo dice che sei in Marocco, con NLS_LANG="ARABIC_MOROCCO.AR8MSWIN1256" :

SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-={}|;.:<>?,./]', ' ') as REG from dual;

REG
------------
TEST 3304 V2

SQL> select value from nls_session_parameters where parameter = 'NLS_SORT';

VALUE
----------
ARABIC

Il motivo è che il segmento del modello +-= viene considerato come un intervallo che copre tutti i caratteri da + a = . Nel set di caratteri ISO8859-1 e Windows 1252 ovvero i caratteri da 43 a 61 e tutte le cifre numeriche rientrano in tale intervallo - ad esempio zero è 48 - rientrano in tale intervallo, quindi la regex le sostituisce. Ciò vale anche per il set di caratteri di Windows 1256 . (E qualsiasi cosa basata su ASCII).

Ma il tuo NLS_LANG sta anche cambiando implicitamente l'ordinamento ed è il passaggio dall'ordinamento BINARY a quello ARABO che cambia il comportamento. Puoi vederlo all'interno di una singola sessione; con NLS_LANG=ENGLISH_UNITED KINGDOM.WE8ISO8859P1 :

SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-={}|;.:<>?,./]', ' ') as REG from dual;

REG
------------
TEST      V

SQL> alter session set NLS_SORT=ARABIC;

Session altered.

SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-={}|;.:<>?,./]', ' ') as REG from dual;

REG
------------
TEST 3304 V2

Puoi anche dire che si tratta di un problema di intervallo modificando leggermente l'intervallo; modificando +-= a +-3 quindi le cifre più alte non sono incluse, ma lasciando tutto il resto uguale:

SQL> alter session set NLS_SORT=BINARY;

Session altered.

SQL> select REGEXP_REPLACE ('TEST 3304 V2', '[`[email protected]#$%^&*()_+-3{}|;.:<>?,./]', ' ') as REG from dual;

REG
------------
TEST    4 V

Ulteriori informazioni sull'ordinamento linguistico .

Affidarsi alle impostazioni NLS è sempre rischioso, quindi è meglio evitare completamente il problema dell'intervallo modificando il modello per avere il trattino all'inizio o alla fine, il che impedisce del tutto di essere visto come un intervallo; ancora come suggerito da Avinash Raj.