我有以下结构的表
mytable(id number,
name varchar2(100),
department varchar2(100),
description varchar2(100));
并在描述栏
上创建了上下文索引 create index myindex on mytable(description)
indextype IS CTXSYS.CONTEXT
parameters(lexer mylex);
description列包含逗号分隔值,当我执行以下搜索时,它会进行OR搜索。
select * from mytable where contains(description,'aaron,lord')>0;
它将描述列的结果作为aaron或lord。
答案 0 :(得分:0)
使用\
或{...}
至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;
<强>问题强>
默认情况下,逗号被视为累积运算符并返回所有四行,因为它们都有&#34; aaron&#34;或者&#34;领主&#34;。
select description from mytable where contains(description,'aaron,lord')>0;
DESCRIPTION
-----------
aaron,lord
aaron
lord
aaron lord
解决方案第1部分 - 转义逗号
转储累加器将阻止ORing并排除&#34; aaron&#34;和&#34;领主&#34;。我假设真正的查询使用绑定变量而不是硬编码,这就是下面的查询使用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函数和条件是否更好。