sql >> Database >  >> RDS >> Oracle

De reguliere expressie van Oracle met een koppelteken geeft niet hetzelfde resultaat op Windows als op Unix

Zoals Avinash Raj in opmerkingen zei, wordt het koppelteken in je reguliere expressiepatroon geïnterpreteerd als een bereik. Het gedrag lijkt afhankelijk te zijn van het sorteeralgoritme dat door de twee clients wordt gebruikt, gebaseerd op de omgevingsvariabele NLS_LANG, die de NLS_SORT-waarde beïnvloedt.

Met 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

Op stap gaan terwijl je profiel zegt dat je in Marokko bent, met 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

De reden is dat het patroonsegment +-= wordt behandeld als een bereik dat alle tekens van + . omvat naar = . In de ISO8859-1 en Windows 1252-tekenset dat wil zeggen tekens 43 tot 61, en alle numerieke cijfers vallen binnen dat bereik - nul is bijvoorbeeld 48 - vallen binnen dat bereik, dus de regex vervangt ze. Dat geldt ook voor de Windows 1256-tekenset . (En alles op basis van ASCII).

Maar je NLS_LANG verandert ook impliciet de sorteervolgorde, en het is de omschakeling van BINARY naar ARABISCHE sortering die het gedrag verandert. Dat zie je binnen één sessie; met 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

Je kunt ook zien dat het een bereikprobleem is door het bereik enigszins aan te passen; wijzigen van +-= naar +-3 dus hogere cijfers zijn niet inbegrepen, maar de rest blijft hetzelfde:

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

Lees meer over taalkundige sortering .

Vertrouwen op NLS-instellingen is echter altijd riskant, dus het is beter om het bereikprobleem volledig te vermijden door het patroon te wijzigen om het koppelteken aan het begin of einde te hebben, waardoor het helemaal niet als een bereik wordt gezien; opnieuw zoals Avinash Raj suggereerde.




  1. SUBDATE() Voorbeelden – MySQL

  2. Genereer alle mogelijke combinaties van strings van bepaalde lengte in orakel

  3. Fix MySQL-waarschuwing 1287:'BINARY expr' is verouderd en zal in een toekomstige release worden verwijderd

  4. Hoe om te leiden naar een andere pagina op gebruikerstype in php en mysql