sql >> Databasteknik >  >> RDS >> Oracle

Oracle reguljära uttryck med bindestreck ger inte samma resultat på Windows som på Unix

Som Avinash Raj sa i kommentarer, tolkas bindestrecket i ditt vanliga uttrycksmönster som ett intervall. Beteendet verkar vara beroende av sorteringsalgoritmen som används av de två klienterna, baserat på miljövariabeln NLS_LANG, som påverkar NLS_SORT-värdet.

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

Att gå ut på ett ben när din profil säger att du är i Marocko, 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

Anledningen är att mönstersegmentet +-= behandlas som ett intervall som täcker alla tecken från + till = . I ISO8859-1 och Windows 1252-teckenuppsättningen det vill säga tecknen 43 till 61, och alla numeriska siffror faller inom det intervallet - noll är till exempel 48 - är inom det intervallet, så det regex ersätter dem. Det är också sant i Windows 1256-teckenuppsättningen . (Och allt baserat på ASCII).

Men din NLS_LANG ändrar också implicit sorteringsordningen, och det är växlingen från BINÄR till ARABISK sortering som ändrar beteendet. Du kan se det inom en enda 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 också se att det är ett intervallproblem genom att ändra intervallet något; ändra +-= till +-3 så högre siffror ingår inte, men lämnar allt annat detsamma:

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 mer om språklig sortering .

Att förlita sig på NLS-inställningar är dock alltid riskabelt, så det är bättre att undvika räckviddsproblemet helt och hållet genom att ändra mönstret till att ha bindestrecket i början eller slutet, vilket gör att det inte alls ses som ett intervall; igen som Avinash Raj föreslog.




  1. Konvertera en rad till flera rader med färre kolumner

  2. Växla till förberedda uttalanden

  3. Hur får man en mysql-fråga att ständigt uppdatera i PHP?

  4. Dynamisk datamaskering i SQL Server för nybörjare