W domyślnym zachowaniu LIKE
i innych operatorach porównania =
itp. Rozróżniana jest wielkość liter.
Czy to możliwe, aby rozróżniała wielkość liter?
sql
oracle
case-sensitive
case-insensitive
sql-like
sergionni
źródło
źródło
REGEXP_LIKE(username,'me','i')
zamiast LIKE?Odpowiedzi:
Od wersji 10gR2 Oracle umożliwia precyzyjne dostosowanie zachowania porównań ciągów poprzez ustawienie parametrów
NLS_COMP
iNLS_SORT
sesji:Możesz także tworzyć indeksy bez rozróżniania wielkości liter:
Informacje te pochodzą z wyszukiwań Oracle bez rozróżniania wielkości liter . Artykuł wspomina,
REGEXP_LIKE
ale wydaje się, że działa również ze starym=
dobrym.W wersjach starszych niż 10gR2 tak naprawdę nie można tego zrobić, a zwykłe podejście, jeśli nie potrzebujesz wyszukiwania niewrażliwego na akcent , dotyczy tylko
UPPER()
kolumny i wyrażenia wyszukiwania.źródło
LIKE
wyrażenia (np.WHERE foo LIKE '%abc%'
) Są już wystarczająco wolne, jeśli nie można ich zindeksować, nie sądzę, żeby miało to związek z rozróżnianiem wielkości liter.DBD::Oracle
, możesz napisać$ENV{NLS_SORT} = 'BINARY_CI'; $ENV{NLS_COMP} = 'LINGUISTIC';
przed wywołaniem `DBI-> connect`.ALTER SESSION
jedyna zmiana zmienia lokalną instancję korekty i oznacza to, że twoja bieżąca sesja to znaczy, że jeśli zamknę i ponownie otworzę, zresetuje się. Czy jest sposób, w jaki mogę zobaczyć, jakie są obecne wartości, więc jeśliIstnieją 3 główne sposoby przeprowadzania wyszukiwania Oracle bez rozróżniania wielkości liter bez użycia indeksów pełnotekstowych.
Ostatecznie wybór metody zależy od indywidualnych okoliczności; Najważniejszą rzeczą do zapamiętania jest to, że aby poprawić wydajność, musisz poprawnie indeksować wyszukiwanie bez rozróżniania wielkości liter.
1. Spraw, by kolumna i ciąg znaków były identyczne.
Możesz wymusić, aby wszystkie dane były identyczne, używając
UPPER()
lubLOWER()
:lub
Jeśli
column_1
nie jest zaindeksowanyupper(column_1)
lublower(column_1)
, w stosownych przypadkach, może to wymusić pełne skanowanie tabeli. Aby tego uniknąć, możesz utworzyć indeks oparty na funkcjach .Jeśli używasz LIKE, musisz łączyć ciąg
%
wokół szukanego ciągu.Ten SQL Fiddle pokazuje, co dzieje się we wszystkich tych zapytaniach. Zwróć uwagę na wyjaśnienia, które wskazują, kiedy indeks jest używany, a kiedy nie.
2. Użyj wyrażeń regularnych.
Od Oracle 10g
REGEXP_LIKE()
jest dostępna. Możesz określić _match_parameter_'i'
, aby przeprowadzić wyszukiwanie bez rozróżniania wielkości liter.Aby użyć tego jako operatora równości, musisz określić początek i koniec łańcucha, który jest oznaczony przez karat i znak dolara.
Aby wykonać odpowiednik LIKE, można je usunąć.
Uważaj na to, ponieważ łańcuch może zawierać znaki, które będą interpretowane w różny sposób przez silnik wyrażeń regularnych.
To skrzypce SQL pokazuje te same przykładowe dane wyjściowe, z wyjątkiem użycia REGEXP_LIKE ().
3. Zmień to na poziomie sesji.
NLS_SORT parametr reguluje kolejność sortowania dla zamawiającego i różnych operatorów porównania, w tym
=
i podobnych. Możesz określić binarne sortowanie bez rozróżniania wielkości liter, zmieniając sesję. Oznacza to, że każde zapytanie wykonane w tej sesji wykona parametry bez rozróżniania wielkości liter.Istnieje wiele dodatkowych informacji na temat sortowania językowego i wyszukiwania ciągów, jeśli chcesz określić inny język lub przeprowadzić wyszukiwanie niewrażliwe na akcent przy użyciu BINARY_AI.
Będziesz także musiał zmienić parametr NLS_COMP ; cytować:
Domyślna wartość NLS_COMP to BINARY; ale LINGUISTIC określa, że Oracle powinno zwracać uwagę na wartość NLS_SORT:
Więc jeszcze raz musisz zmienić sesję
Jak zauważono w dokumentacji, możesz chcieć utworzyć indeks językowy w celu poprawy wydajności
źródło
select * from my_table where lower(column_1) LIKE lower('my_string') || '%';
zamiastselect * from my_table where lower(column_1) LIKE lower('my_string%');
? Czy daje to jakąś przewagę?regexp_like
, czy istnieje sposób na uniknięcie takich ciągów? Podając przykład, jeśli ciąg ma $, wynik nie będzie zgodny z oczekiwaniami. // cc @Ben i inni, proszę, udostępnij.`
jest znakiem ucieczki @bozzmob. Nie powinno być różnicy w danych wyjściowych, jeśli ciąg, na którym działa wyrażenie regularne, zawiera a$
, może to powodować problemy tylko wtedy, gdy potrzebujesz$
literału w wyrażeniu regularnym. Jeśli masz konkretny problem, zadam inne pytanie, czy ten komentarz / odpowiedź nie pomogła.może możesz spróbować użyć
źródło
WHERE upper(user_name) LIKE UPPER('%ME%')
wtedy? :)UPPER
też parametru wejściowego?upper
funkcji tracisz indeks, czy masz pomysł, jak wyszukiwać za pomocą indeksu?Z Oracle 12c R2 możesz użyć
COLLATE operator
:Próbny:
db <> demo skrzypiec
źródło
źródło
%
„s w pierwszym argumencie do drugiegoNLSSORT
są nie miało być symbole wieloznaczne, prawda? Trochę mylą.możesz zrobić coś takiego:
źródło