使用\ 或{...} 到escape accumulate operators。
示例架构
--drop table mytable;
create table mytable(id number,
name varchar2(100),
department varchar2(100),
description varchar2(100));
insert into mytable values(1, 'A', 'A', 'aaron,lord');
insert into mytable values(2, 'B', 'B', 'aaron');
insert into mytable values(3, 'C', 'C', 'lord');
commit;
create index myindex on mytable(description)
indextype IS CTXSYS.CONTEXT;
问题
默认情况下,逗号被视为累加运算符并返回所有四行,因为它们都有“aaron”或“lord”。
select description from mytable where contains(description,'aaron,lord')>0;
DESCRIPTION
-----------
aaron,lord
aaron
lord
aaron lord
解决方案第 1 部分 - 转义逗号
转义累加器将阻止 ORing 并排除“aaron”和“lord”。我假设真正的查询使用绑定变量并且没有硬编码,这就是为什么下面的查询使用REPLACE 或|| 而不是简单地修改字符串。
select description from mytable where contains(description, replace('aaron,lord', ',', '\,')) > 0;
select description from mytable where contains(description, '{' || 'aaron,lord' || '}') > 0;
DESCRIPTION
-----------
aaron,lord
aaron lord
解决方案第 2 部分 - 在 printjoin 中添加逗号
drop index myindex;
begin
ctx_ddl.create_preference('mylex', 'BASIC_LEXER');
ctx_ddl.set_attribute('mylex', 'printjoins', ',');
end;
/
create index myindex on mytable(description)
indextype IS CTXSYS.CONTEXT
parameters ('LEXER mylex');
现在只会返回一行。
select description from mytable where contains(description, replace('aaron,lord', ',', '\,')) > 0;
select description from mytable where contains(description, '{' || 'aaron,lord' || '}') > 0;
DESCRIPTION
-----------
aaron,lord
但是结果变得如此具体,我想知道是否最好避免使用CONTAINS,而只使用常规 SQL 函数和条件。