sql >> Databáze >  >> RDS >> Oracle

Regulární výraz Oracle s pomlčkou nedává ve Windows stejný výsledek jako v Unixu

Jak řekl Avinash Raj v komentářích, spojovník ve vašem vzoru regulárního výrazu je interpretován jako rozsah. Zdá se, že chování závisí na třídicím algoritmu používaném dvěma klienty na základě proměnné prostředí NLS_LANG, která ovlivňuje hodnotu NLS_SORT.

S 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

Vydejte se na volno, protože váš profil říká, že jste v Maroku, s 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

Důvodem je segment vzoru +-= je považováno za rozsah zahrnující všechny znaky z + na = . Ve znakové sadě ISO8859-1 a znakové sadě Windows 1252 to jsou znaky 43 až 61 a všechny číselné číslice spadají do tohoto rozsahu - nula je například 48 - jsou v tomto rozsahu, takže je nahradí regulární výraz. To platí také pro znakovou sadu Windows 1256 . (A cokoli založeného na ASCII).

Ale váš NLS_LANG také implicitně mění pořadí řazení a je to přepnutí z BINARY na ARABIC řazení, které mění chování. Můžete to vidět během jedné relace; s 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

To, že se jedná o problém s rozsahem, poznáte také mírnou úpravou rozsahu; změna +-= na +-3 takže vyšší číslice nejsou zahrnuty, ale vše ostatní zůstává stejné:

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

Přečtěte si další informace o lingvistickém třídění .

Spoléhat se na nastavení NLS je však vždy riskantní, takže je lepší se problému s rozsahem zcela vyhnout tím, že změníte vzor tak, aby měl pomlčku na začátku nebo na konci, což přestane být vnímáno jako rozsah; znovu, jak navrhl Avinash Raj.




  1. Funkce NEW_TIME() v Oracle

  2. Získáváte umístění a název souboru externí tabulky?

  3. Výkon SQL pro vyhledávání dlouhých řetězců

  4. Podporuje některý ovladač JDBC příkaz LOAD DATA INFILE sql?