it-swarm.com.de

Groß- und Kleinschreibung wird in Oracle nicht berücksichtigt

Das Standardverhalten von LIKE und den anderen Vergleichsoperatoren = etc unterscheidet zwischen Groß- und Kleinschreibung.

Ist es möglich, sie zwischen Groß- und Kleinschreibung zu unterscheiden?

210
sergionni

Seit 10gR2 ermöglicht Oracle die Feinabstimmung des Verhaltens von Zeichenfolgenvergleichen durch Festlegen der Sitzungsparameter NLS_COMP und NLS_SORT :

SQL> SET HEADING OFF
SQL> SELECT *
  2  FROM NLS_SESSION_PARAMETERS
  3  WHERE PARAMETER IN ('NLS_COMP', 'NLS_SORT');

NLS_SORT
BINARY

NLS_COMP
BINARY


SQL>
SQL> SELECT CASE WHEN 'abc'='ABC' THEN 1 ELSE 0 END AS GOT_MATCH
  2  FROM DUAL;

         0

SQL>
SQL> ALTER SESSION SET NLS_COMP=LINGUISTIC;

Session altered.

SQL> ALTER SESSION SET NLS_SORT=BINARY_CI;

Session altered.

SQL>
SQL> SELECT *
  2  FROM NLS_SESSION_PARAMETERS
  3  WHERE PARAMETER IN ('NLS_COMP', 'NLS_SORT');

NLS_SORT
BINARY_CI

NLS_COMP
LINGUISTIC


SQL>
SQL> SELECT CASE WHEN 'abc'='ABC' THEN 1 ELSE 0 END AS GOT_MATCH
  2  FROM DUAL;

         1

Sie können auch Indizes ohne Berücksichtigung der Groß- und Kleinschreibung erstellen:

create index
   nlsci1_gen_person
on
   MY_PERSON
   (NLSSORT
      (PERSON_LAST_NAME, 'NLS_SORT=BINARY_CI')
   )
;

Diese Informationen stammen aus Suche ohne Berücksichtigung der Groß- und Kleinschreibung in Oracle . Der Artikel erwähnt REGEXP_LIKE, Aber es scheint auch mit guten alten = Zu funktionieren.


In Versionen, die älter als 10gR2 sind, kann dies nicht wirklich durchgeführt werden. Wenn Sie keine Suche akzentunabhängig benötigen, besteht der übliche Ansatz darin, nur UPPER() beide Spalten zu durchsuchen und der Suchausdruck.

77

Es gibt drei Hauptmethoden, um in Oracle eine Suche ohne Berücksichtigung der Groß- und Kleinschreibung durchzuführen, ohne Volltextindizes zu verwenden.

Letztendlich hängt die von Ihnen gewählte Methode von Ihren individuellen Umständen ab. Um die Leistung zu verbessern, müssen Sie für die Suche ohne Berücksichtigung der Groß- und Kleinschreibung den richtigen Index festlegen.

1. Schließe deine Spalte und deinen String identisch ab.

Sie können erzwingen, dass alle Ihre Daten gleich sind, indem Sie UPPER() oder LOWER() verwenden:

select * from my_table where upper(column_1) = upper('my_string');

oder

select * from my_table where lower(column_1) = lower('my_string');

Wenn column_1 Für upper(column_1) oder lower(column_1) nicht indiziert ist, wird möglicherweise ein vollständiger Tabellenscan erzwungen. Um dies zu vermeiden, können Sie einen funktionsbasierten Index erstellen.

create index my_index on my_table ( lower(column_1) );

Wenn Sie LIKE verwenden, müssen Sie einen % Um den gesuchten String verketten.

select * from my_table where lower(column_1) LIKE lower('my_string') || '%';

This SQL Fiddle zeigt, was in all diesen Abfragen passiert. Beachten Sie die Erklärungspläne, die angeben, wann ein Index verwendet wird und wann nicht.

2. Verwenden Sie reguläre Ausdrücke.

Ab Oracle 10g ist REGEXP_LIKE() verfügbar. Sie können den _match_parameter_ 'i' Angeben, um eine Suche ohne Berücksichtigung der Groß-/Kleinschreibung durchzuführen.

Um dies als Gleichheitsoperator zu verwenden, müssen Sie den Anfang und das Ende der Zeichenfolge angeben, die durch das Karat- und das Dollarzeichen gekennzeichnet sind.

select * from my_table where regexp_like(column_1, '^my_string$', 'i');

Um das Äquivalent von LIKE durchzuführen, können diese entfernt werden.

select * from my_table where regexp_like(column_1, 'my_string', 'i');

Seien Sie vorsichtig damit, da Ihre Zeichenfolge möglicherweise Zeichen enthält, die vom Modul für reguläre Ausdrücke unterschiedlich interpretiert werden.

Diese SQL-Geige zeigt Ihnen die gleiche Beispielausgabe, außer dass Sie REGEXP_LIKE () verwenden.

3. Ändern Sie es auf der Sitzungsebene.

Der Parameter NLS_SORT regelt die Sortierfolge für die Bestellung und die verschiedenen Vergleichsoperatoren, einschließlich = Und LIKE. Sie können eine binäre Sortierung festlegen, bei der die Groß- und Kleinschreibung nicht berücksichtigt wird, indem Sie die Sitzung ändern. Dies bedeutet, dass bei jeder in dieser Sitzung ausgeführten Abfrage die Groß- und Kleinschreibung nicht berücksichtigt wird.

alter session set nls_sort=BINARY_CI

Es gibt viele zusätzliche Informationen rund um linguistische Sortierung und Suche nach Zeichenfolgen , wenn Sie eine andere Sprache angeben oder eine akzentunabhängige Suche mit BINARY_AI durchführen möchten.

Sie müssen auch den Parameter NLS_COMP ändern. zitieren:

Die genauen Operatoren und Abfrageklauseln, die dem Parameter NLS_SORT entsprechen, hängen vom Wert des Parameters NLS_COMP ab. Wenn ein Operator oder eine Klausel den von NLS_COMP festgelegten NLS_SORT-Wert nicht einhält, wird die Sortierung BINARY verwendet.

Der Standardwert von NLS_COMP ist BINARY. LINGUISTIC gibt jedoch an, dass Oracle auf den Wert von NLS_SORT achten soll:

Vergleiche für alle SQL-Operationen in der WHERE-Klausel und in PL/SQL-Blöcken sollten die im Parameter NLS_SORT angegebene linguistische Sortierung verwenden. Um die Leistung zu verbessern, können Sie auch einen Sprachindex für die Spalte definieren, für die Sie Sprachvergleiche wünschen.

Also müssen Sie die Sitzung noch einmal ändern

alter session set nls_comp=LINGUISTIC

Wie in der Dokumentation angegeben, möchten Sie möglicherweise einen Sprachindex erstellen, um die Leistung zu verbessern

create index my_linguistc_index on my_table 
   (NLSSORT(column_1, 'NLS_SORT = BINARY_CI'));
281
Ben

vielleicht kannst du es mit versuchen

SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'
49
V4Vendetta

Ab Oracle 12c R2 können Sie COLLATE operator :

Der Operator COLLATE bestimmt die Sortierung für einen Ausdruck. Mit diesem Operator können Sie die von der Datenbank für den Ausdruck abgeleitete Kollatierung mithilfe von Standardregeln für die Kollatierungsableitung überschreiben.

Der COLLATE-Operator verwendet ein Argument, collation_name, für das Sie eine benannte Kollatierung oder eine Pseudokollatierung angeben können. Wenn der Kollatierungsname ein Leerzeichen enthält, müssen Sie den Namen in doppelte Anführungszeichen setzen.

Demo:

CREATE TABLE tab1(i INT PRIMARY KEY, name VARCHAR2(100));

INSERT INTO tab1(i, name) VALUES (1, 'John');
INSERT INTO tab1(i, name) VALUES (2, 'Joe');
INSERT INTO tab1(i, name) VALUES (3, 'Billy'); 
--========================================================================--
SELECT /*csv*/ *
FROM tab1
WHERE name = 'jOHN' ;
-- no rows selected

SELECT /*csv*/ *
FROM tab1
WHERE name COLLATE BINARY_CI = 'jOHN' ;
/*
"I","NAME"
1,"John"
*/

SELECT /*csv*/ *
FROM tab1 
WHERE name LIKE 'j%';
-- no rows selected

SELECT /*csv*/ *
FROM tab1 
WHERE name COLLATE BINARY_CI LIKE 'j%';
/*
"I","NAME"
1,"John"
2,"Joe"
*/

db <> fiddle demo

6
Lukasz Szozda
select user_name
from my_table
where nlssort(user_name, 'NLS_SORT = Latin_CI') = nlssort('%AbC%', 'NLS_SORT = Latin_CI')
2
Clodoaldo Neto

sie können so etwas tun:

where regexp_like(name, 'string$', 'i');
1
grep