Ve LIKE
diğer karşılaştırma işleçlerinin varsayılan davranışı büyük / =
küçük harfe duyarlıdır.
Onları büyük / küçük harfe duyarsız hale getirmek mümkün mü?
REGEXP_LIKE(username,'me','i')
LIKE yerine kullanmayı düşündünüz mü ?
Ve LIKE
diğer karşılaştırma işleçlerinin varsayılan davranışı büyük / =
küçük harfe duyarlıdır.
Onları büyük / küçük harfe duyarsız hale getirmek mümkün mü?
REGEXP_LIKE(username,'me','i')
LIKE yerine kullanmayı düşündünüz mü ?
Yanıtlar:
10gR2'den beri Oracle, NLS_COMP
ve NLS_SORT
session parametrelerini ayarlayarak dize karşılaştırmalarının davranışında ince ayar yapmaya izin verir :
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
Büyük / küçük harfe duyarlı olmayan dizinler de oluşturabilirsiniz:
create index
nlsci1_gen_person
on
MY_PERSON
(NLSSORT
(PERSON_LAST_NAME, 'NLS_SORT=BINARY_CI')
)
;
Bu bilgiler, Oracle'ın büyük / küçük harfe duyarlı olmayan aramalarından alınmıştır . Makale bahsediyor REGEXP_LIKE
ama iyi eski =
ile de çalışıyor gibi görünüyor .
10gR2'den eski sürümlerde bu gerçekten yapılamaz ve aksan duyarsız aramaya ihtiyacınız yoksa, normal yaklaşım UPPER()
hem sütun hem de arama ifadesidir.
LIKE
ifadeler (örneğin WHERE foo LIKE '%abc%'
) dizine eklenemezlerse yeterince yavaşlar, özellikle büyük / küçük harf duyarlılığıyla ilgili olduğunu düşünmüyorum.
DBD::Oracle
, $ENV{NLS_SORT} = 'BINARY_CI'; $ENV{NLS_COMP} = 'LINGUISTIC';
`DBI-> connect` çağırmadan önce yazabilirsiniz.
ALTER SESSION
sadece düzeltme yerel örneğinizi değiştirir ve geçerli oturum gibi yani yani kapatıp yeniden açarsanız sıfırlama olurdu anlamına mı geliyor. Mevcut değerlerin ne olduğunu görebilmemin bir yolu var mı, eğer her yerde ısrar ederse orijinal ayarlara geri dönebilirim ...
Oracle'da tam metin dizinleri kullanmadan büyük / küçük harfe duyarlı olmayan bir arama yapmanın 3 ana yolu vardır.
Nihayetinde hangi yöntemi seçtiğiniz bireysel koşullarınıza bağlıdır; hatırlanması gereken en önemli şey, performansı artırmak için büyük / küçük harfe duyarlı olmayan arama için doğru bir şekilde indekslemeniz gerektiğidir.
Sen kullanarak aynı durumda olmak tüm verilerinizi zorlayabilir UPPER()
ya LOWER()
:
select * from my_table where upper(column_1) = upper('my_string');
veya
select * from my_table where lower(column_1) = lower('my_string');
Eğer column_1
üzerinde endeksli değildir upper(column_1)
ya lower(column_1)
uygun olarak, bu tam bir tablo taraması zorlayabilir. Bundan kaçınmak için işlev tabanlı bir dizin oluşturabilirsiniz .
create index my_index on my_table ( lower(column_1) );
LIKE kullanıyorsanız %
, aradığınız dizenin etrafında bir araya getirmeniz gerekir .
select * from my_table where lower(column_1) LIKE lower('my_string') || '%';
Bu SQL Fiddle , tüm bu sorgularda neler olduğunu gösterir. Bir dizinin ne zaman kullanıldığını ve ne zaman kullanılmadığını gösteren Açıklama Planlarını not edin.
Oracle 10g'den itibaren REGEXP_LIKE()
kullanılabilir. Büyük / 'i'
küçük harfe duyarlı olmayan arama yapmak için _match_parameter_ belirtebilirsiniz .
Bunu bir eşitlik operatörü olarak kullanmak için, karat ve dolar işareti ile belirtilen dizenin başlangıcını ve bitişini belirtmelisiniz.
select * from my_table where regexp_like(column_1, '^my_string$', 'i');
LIKE eşdeğerini gerçekleştirmek için bunlar çıkarılabilir.
select * from my_table where regexp_like(column_1, 'my_string', 'i');
Dizeniz normal ifade motoru tarafından farklı yorumlanacak karakterler içerebileceğinden buna dikkat edin.
Bu SQL Fiddle size REGEXP_LIKE () kullanımı dışında aynı örnek çıktıyı gösterir.
NLS_SORT parametre sıralaması ve çeşitli karşılaştırma operatörleri, dahil olmak üzere harmanlama sırasını düzenleyen =
ve benzerlerini içerir. Oturumu değiştirerek ikili, büyük / küçük harfe duyarlı olmayan bir sıralama belirleyebilirsiniz. Bu, bu oturumda gerçekleştirilen her sorgunun büyük / küçük harfe duyarlı olmayan parametreler gerçekleştireceği anlamına gelir.
alter session set nls_sort=BINARY_CI
Farklı bir dil belirtmek veya BINARY_AI kullanarak aksanı duyarsız bir arama yapmak istiyorsanız, dilsel sıralama ve dize araması hakkında birçok ek bilgi vardır.
Ayrıca NLS_COMP parametresini değiştirmeniz gerekecektir ; alıntılamak:
NLS_SORT parametresine uyan tam işleçler ve sorgu cümleleri NLS_COMP parametresinin değerine bağlıdır. Bir işleç veya yan tümce NLS_COMP tarafından belirlenen NLS_SORT değerine uymuyorsa, kullanılan harmanlama BINARY olur.
Varsayılan NLS_COMP değeri BINARY; ancak LINGUISTIC, Oracle'ın NLS_SORT değerine dikkat etmesi gerektiğini belirtir:
WHERE deyimindeki ve PL / SQL bloklarındaki tüm SQL işlemleri için karşılaştırmalar NLS_SORT parametresinde belirtilen dilbilimsel sıralamayı kullanmalıdır. Performansı artırmak için, dil üzerinde karşılaştırma yapmak istediğiniz sütunda bir dil dizini tanımlayabilirsiniz.
Yani, bir kez daha, oturumu değiştirmeniz gerekiyor
alter session set nls_comp=LINGUISTIC
Belgelerde belirtildiği gibi, performansı artırmak için bir dil dizini oluşturmak isteyebilirsiniz
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') || '%';
Bunun yerine neden farklı olduğunu sorabilir miyim select * from my_table where lower(column_1) LIKE lower('my_string%');
? Herhangi bir avantaj sağlıyor mu?
regexp_like
, bu dizelerden kaçmanın bir yolu var mı? Bir örnek vermek gerekirse, dizede $ varsa çıktı beklediğimiz gibi olmayacaktır. // cc @Ben ve diğerleri lütfen paylaşın.
`
@bozzmob çıkış karakteridir . Normal ifadenin üzerinde çalıştığı dize a içeriyorsa, çıktıda herhangi bir fark olmamalıdır $
, bu yalnızca $
normal ifadenizde bir değişmez ifadeye ihtiyacınız varsa sorunlara neden olabilir . Belirli bir sorununuz varsa, bu yorum / yanıt yardımcı olmadıysa başka bir soru soracağım.
belki kullanmayı deneyebilirsin
SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'
WHERE upper(user_name) LIKE UPPER('%ME%')
? :)
UPPER
giriş parametresinde de kullanmıyorsunuz ?
upper
indeksi kaybettiğiniz fonksiyonu kullanarak, indeksi kullanarak nasıl arama yapılacağına dair bir fikriniz var mı?
Oracle 12c R2'den şunları kullanabilirsiniz COLLATE operator
:
COLLATE işleci, bir ifadenin harmanlamasını belirler. Bu işleç, standart harmanlama türetme kurallarını kullanarak veritabanının ifade için türeteceği harmanlamayı geçersiz kılmanıza olanak tanır.
COLLATE işleci, adlandırılmış bir harmanlama veya sözde harmanlama belirtebileceğiniz bir collation_name argümanı alır. Harmanlama adı boşluk içeriyorsa, adı çift tırnak içine almanız gerekir.
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')
%
Senin kapatıldığı ikinci argüman 'ın NLSSORT
edilir değil , doğru joker olması gerekiyordu? Biraz kafa karıştırıyorlar.