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

Oracle regulære udtryk med en bindestreg giver ikke samme resultat på Windows som på Unix

Som Avinash Raj sagde i kommentarer, bliver bindestregen i dit regulære udtryksmønster fortolket som et interval. Adfærden ser ud til at være afhængig af den sorteringsalgoritme, der bruges af de to klienter, baseret på miljøvariablen NLS_LANG, som påvirker NLS_SORT-værdien.

Med 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

Går ud på et ben, da din profil siger, at du er i Marokko, med 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

Årsagen er, at mønstersegmentet +-= behandles som et område, der dækker alle tegn fra + til = . I ISO8859-1 og Windows 1252-tegnsættet det vil sige tegnene 43 til 61, og alle de numeriske cifre falder inden for dette område - nul er f.eks. 48 - er inden for dette område, så det regex erstatter dem. Det gælder også i Windows 1256-tegnsættet . (Og alt baseret på ASCII).

Men din NLS_LANG ændrer også implicit sorteringsrækkefølgen, og det er skift fra BINÆR til ARABISK sortering, der ændrer adfærden. Du kan se det inden for en enkelt session; med 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

Du kan også se, at det er et områdeproblem ved at ændre rækkevidden en smule; ændre +-= til +-3 så højere cifre er ikke inkluderet, men lader alt andet være det samme:

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

Læs mere om sproglig sortering .

At stole på NLS-indstillinger er dog altid risikabelt, så det er bedre at undgå områdeproblemet helt ved at ændre mønsteret til at have bindestregen i begyndelsen eller slutningen, hvilket forhindrer det i at blive set som et område overhovedet; igen som Avinash Raj foreslog.




  1. Opdeling af kommasepareret streng i PL/pgSQL-funktion

  2. Sådan opdaterer du en kolonne baseret på et filter af en anden kolonne

  3. Sådan forstår du statistik over sporingsfiler i Oracle. Såsom CPU, forløbet tid, forespørgsel...osv

  4. PHP:Hent billede fra MySQL ved hjælp af PDO