LIKE
和其他比较运算符=
等的默认行为区分大小写。
是否可以使它们不区分大小写?
REGEXP_LIKE(username,'me','i')
替代LIKE?
LIKE
和其他比较运算符=
等的默认行为区分大小写。
是否可以使它们不区分大小写?
REGEXP_LIKE(username,'me','i')
替代LIKE?
Answers:
从10gR2开始,Oracle允许通过设置NLS_COMP
和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
您还可以创建不区分大小写的索引:
create index
nlsci1_gen_person
on
MY_PERSON
(NLSSORT
(PERSON_LAST_NAME, 'NLS_SORT=BINARY_CI')
)
;
此信息来自Oracle不区分大小写的搜索。文章提到了,REGEXP_LIKE
但似乎也适用于旧版本=
。
在10gR2之前的版本中,这实际上是不可能完成的,并且如果不需要不需要重音符号的搜索,通常的方法是只UPPER()
对列和搜索表达式都使用。
LIKE
表达式(例如WHERE foo LIKE '%abc%'
)如果不能被索引已经足够慢,我不认为它与大小写敏感度特别相关。
DBD::Oracle
,您可以$ENV{NLS_SORT} = 'BINARY_CI'; $ENV{NLS_COMP} = 'LINGUISTIC';
在调用`DBI-> connect`之前编写。
ALTER SESSION
只会更改您的本地更正实例,这是否意味着像您当前的会话,即如果我关闭并重新打开它将会重置。有没有一种方法可以让我看到当前值,因此如果它在所有地方都持续存在,我可以更改回原始设置...
在不使用全文索引的情况下,可以通过3种主要方法在Oracle中执行不区分大小写的搜索。
最终,您选择哪种方法取决于您的个人情况。要记住的主要事情是,为了提高性能,必须为不区分大小写的搜索正确地建立索引。
您可以使用UPPER()
或强制所有数据都使用相同的大小写LOWER()
:
select * from my_table where upper(column_1) = upper('my_string');
要么
select * from my_table where lower(column_1) = lower('my_string');
如果column_1
未在upper(column_1)
或上建立索引lower(column_1)
,则可能会强制执行全表扫描。为了避免这种情况,您可以创建基于函数的index。
create index my_index on my_table ( lower(column_1) );
如果您使用的是LIKE,则必须在%
要搜索的字符串周围连接一个。
select * from my_table where lower(column_1) LIKE lower('my_string') || '%';
此SQL Fiddle演示了所有这些查询中发生的情况。注意说明计划,该计划指示何时使用索引,何时不使用索引。
从Oracle 10g开始REGEXP_LIKE()
可用。您可以指定_match_parameter_ 'i'
,以执行不区分大小写的搜索。
为了将其用作相等运算符,您必须指定字符串的开始和结束,以克拉和美元符号表示。
select * from my_table where regexp_like(column_1, '^my_string$', 'i');
为了执行等效的LIKE,可以将其删除。
select * from my_table where regexp_like(column_1, 'my_string', 'i');
请注意这一点,因为您的字符串可能包含正则表达式引擎将以不同的方式解释的字符。
除了使用REGEXP_LIKE()之外,此SQL Fiddle还显示了相同的示例输出。
所述NLS_SORT参数控制为排序和各种比较运算符,包括归类序列=
和类似物。您可以通过更改会话来指定不区分大小写的二进制排序。这意味着在该会话中执行的每个查询都将执行不区分大小写的参数。
alter session set nls_sort=BINARY_CI
如果要指定其他语言,或者要使用BINARY_AI进行不区分重音的搜索,则还有很多其他信息与语言排序和字符串搜索有关。
您还需要更改NLS_COMP参数。报价:
服从NLS_SORT参数的确切运算符和查询子句取决于NLS_COMP参数的值。如果运算符或子句不遵循NLS_COMP确定的NLS_SORT值,则使用的归类为BINARY。
NLS_COMP的默认值为BINARY;但是,LINGUISTIC指定Oracle应该注意NLS_SORT的值:
WHERE子句和PL / SQL块中所有SQL操作的比较应使用NLS_SORT参数中指定的语言排序。为了提高性能,您还可以在要进行语言比较的列上定义语言索引。
因此,再次,您需要更改会话
alter session set nls_comp=LINGUISTIC
如文档中所述,您可能需要创建语言索引以提高性能
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') || '%';
,而不是 select * from my_table where lower(column_1) LIKE lower('my_string%');
?有什么好处吗?
regexp_like
,是否有一种方法可以转义此类字符串?举个例子,如果字符串中有$,则输出将不会达到我们的预期。// cc @Ben和其他人请分享。
也许你可以尝试使用
SELECT user_name
FROM user_master
WHERE upper(user_name) LIKE '%ME%'
WHERE upper(user_name) LIKE UPPER('%ME%')
吗 :)
UPPER
在输入参数上使用呢?
upper
丢失索引的函数,您是否知道如何使用索引进行搜索?
在Oracle 12c R2中,您可以使用COLLATE operator
:
COLLATE运算符确定表达式的排序规则。使用此运算符,您可以使用标准归类派生规则来覆盖数据库为该表达式派生的归类。
COLLATE运算符采用一个参数collation_name,您可以为其指定命名的归类或伪归类。如果排序规则名称包含空格,则必须用双引号将该名称引起来。
演示:
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')
%
的第一个参数,以你的第二个NLSSORT
是不是意味着是通配符,对不对?他们有点困惑。