Perilaku default LIKE
dan operator pembanding lainnya, =
dll peka huruf besar-kecil.
Apakah mungkin membuat mereka tidak peka terhadap huruf besar-kecil?
REGEXP_LIKE(username,'me','i')
bukannya LIKE?
Perilaku default LIKE
dan operator pembanding lainnya, =
dll peka huruf besar-kecil.
Apakah mungkin membuat mereka tidak peka terhadap huruf besar-kecil?
REGEXP_LIKE(username,'me','i')
bukannya LIKE?
Jawaban:
Sejak 10gR2, Oracle memungkinkan untuk menyempurnakan perilaku perbandingan string dengan mengatur parameter NLS_COMP
dan NLS_SORT
sesi:
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
Anda juga dapat membuat indeks case sensitive:
create index
nlsci1_gen_person
on
MY_PERSON
(NLSSORT
(PERSON_LAST_NAME, 'NLS_SORT=BINARY_CI')
)
;
Informasi ini diambil dari pencarian tidak sensitif case Oracle . Artikel itu menyebutkan REGEXP_LIKE
tetapi tampaknya bekerja dengan baik =
juga.
Dalam versi yang lebih tua dari 10gR2 itu tidak dapat benar-benar dilakukan dan pendekatan yang biasa, jika Anda tidak memerlukan pencarian tidak peka-aksen , adalah hanya UPPER()
kolom dan ekspresi pencarian.
LIKE
Ekspresi sewenang-wenang (misalnya WHERE foo LIKE '%abc%'
) sudah cukup lambat jika mereka tidak dapat diindeks, saya tidak berpikir itu terkait dengan sensitivitas huruf.
DBD::Oracle
, Anda dapat menulis $ENV{NLS_SORT} = 'BINARY_CI'; $ENV{NLS_COMP} = 'LINGUISTIC';
sebelum memanggil `DBI-> connect`.
ALTER SESSION
hanya mengubah instance lokal Anda dari koreksi dan apakah itu berarti seperti sesi Anda saat ini yaitu jika saya menutup dan membuka kembali itu akan reset. Apakah ada cara agar saya dapat melihat apa nilai saat ini sehingga jika tetap ada di mana-mana saya dapat kembali ke pengaturan semula ...
Ada 3 cara utama untuk melakukan pencarian case-insensitive di Oracle tanpa menggunakan indeks teks lengkap.
Pada akhirnya, metode apa yang Anda pilih bergantung pada keadaan pribadi Anda; hal utama yang harus diingat adalah untuk meningkatkan kinerja Anda harus mengindeks dengan benar untuk pencarian case-sensitive.
Anda dapat memaksa semua data Anda menjadi kasus yang sama dengan menggunakan UPPER()
atau LOWER()
:
select * from my_table where upper(column_1) = upper('my_string');
atau
select * from my_table where lower(column_1) = lower('my_string');
Jika column_1
tidak diindeks pada upper(column_1)
atau lower(column_1)
, jika sesuai, ini mungkin memaksa pemindaian tabel penuh. Untuk menghindari ini, Anda dapat membuat indeks berbasis fungsi .
create index my_index on my_table ( lower(column_1) );
Jika Anda menggunakan LIKE maka Anda harus menyatukan %
sekitar string yang Anda cari.
select * from my_table where lower(column_1) LIKE lower('my_string') || '%';
SQL Fiddle ini menunjukkan apa yang terjadi di semua kueri ini. Perhatikan Rencana Jelaskan, yang menunjukkan kapan indeks digunakan dan kapan tidak.
Dari Oracle 10g dan seterusnya REGEXP_LIKE()
tersedia. Anda dapat menentukan _match_parameter_ 'i'
, untuk melakukan pencarian case-insensitive.
Untuk menggunakan ini sebagai operator kesetaraan, Anda harus menentukan awal dan akhir string, yang dilambangkan dengan karat dan tanda dolar.
select * from my_table where regexp_like(column_1, '^my_string$', 'i');
Untuk melakukan yang setara dengan LIKE, ini dapat dihapus.
select * from my_table where regexp_like(column_1, 'my_string', 'i');
Hati-hati dengan ini karena string Anda mungkin berisi karakter yang akan ditafsirkan berbeda oleh mesin ekspresi reguler.
SQL Fiddle ini menunjukkan kepada Anda contoh output yang sama kecuali menggunakan REGEXP_LIKE ().
The NLS_SORT parameter mengatur urutan pemeriksaan untuk pemesanan dan berbagai operator perbandingan, termasuk =
dan SEBAGAINYA. Anda bisa menentukan jenis biner, tidak peka huruf besar-kecil, dengan mengubah sesi. Ini berarti bahwa setiap kueri yang dilakukan dalam sesi itu akan melakukan parameter case-insensitive.
alter session set nls_sort=BINARY_CI
Ada banyak informasi tambahan seputar penyortiran linguistik dan pencarian string jika Anda ingin menentukan bahasa yang berbeda, atau melakukan pencarian yang peka terhadap aksen menggunakan BINARY_AI.
Anda juga perlu mengubah parameter NLS_COMP ; kutipan:
Operator yang tepat dan klausa permintaan yang mematuhi parameter NLS_SORT tergantung pada nilai parameter NLS_COMP. Jika operator atau klausa tidak mematuhi nilai NLS_SORT, seperti yang ditentukan oleh NLS_COMP, susunan yang digunakan adalah BINARY.
Nilai default NLS_COMP adalah BINARY; tetapi, LINGUISTIC menetapkan bahwa Oracle harus memperhatikan nilai NLS_SORT:
Perbandingan untuk semua operasi SQL di klausa WHERE dan di PL / SQL blok harus menggunakan jenis linguistik yang ditentukan dalam parameter NLS_SORT. Untuk meningkatkan kinerja, Anda juga dapat menentukan indeks linguistik pada kolom yang Anda inginkan perbandingan linguistik.
Jadi, sekali lagi, Anda perlu mengubah sesi
alter session set nls_comp=LINGUISTIC
Sebagaimana dicatat dalam dokumentasi Anda mungkin ingin membuat indeks linguistik untuk meningkatkan kinerja
create index my_linguistc_index on my_table
(NLSSORT(column_1, 'NLS_SORT = BINARY_CI'));
select * from my_table where lower(column_1) LIKE lower('my_string') || '%';
daripada melakukan select * from my_table where lower(column_1) LIKE lower('my_string%');
? Apakah ada manfaatnya?
regexp_like
, apakah ada cara untuk melarikan diri dari string seperti itu? Memberi contoh, jika string memiliki $, output tidak akan seperti yang kita harapkan. // cc @Ben dan yang lainnya tolong lakukan berbagi.
`
adalah karakter escape @bozzmob. Seharusnya tidak ada perbedaan dalam output jika string ekspresi reguler beroperasi berisi $
, ini hanya dapat menyebabkan masalah jika Anda memerlukan $
literal dalam ekspresi reguler Anda. Jika Anda memiliki masalah tertentu, saya akan mengajukan pertanyaan lain jika komentar / jawaban ini tidak membantu.
mungkin Anda bisa mencoba menggunakan
SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'
WHERE upper(user_name) LIKE UPPER('%ME%')
? :)
UPPER
parameter input juga?
upper
fungsi Anda kehilangan indeks, apakah Anda tahu cara melakukan pencarian menggunakan indeks?
Dari Oracle 12c R2 Anda dapat menggunakan COLLATE operator
:
Operator COLLATE menentukan collation untuk ekspresi. Operator ini memungkinkan Anda untuk mengganti susunan yang akan dihasilkan oleh basis data untuk ekspresi menggunakan aturan derivasi susunan standar.
Operator COLLATE mengambil satu argumen, collation_name, yang Anda dapat menentukan collation bernama atau pseudo-collation. Jika nama collation berisi spasi, maka Anda harus menyertakan nama dalam tanda kutip ganda.
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"
*/
select user_name
from my_table
where nlssort(user_name, 'NLS_SORT = Latin_CI') = nlssort('%AbC%', 'NLS_SORT = Latin_CI')
%
's dalam argumen pertama untuk kedua Anda NLSSORT
yang tidak dimaksudkan untuk menjadi wildcard, kan? Mereka agak bingung.