Oracle содержит поиск с Apostrope - PullRequest
0 голосов
/ 13 декабря 2018

Я использую Oracle 11g, и у меня есть таблица с именем test со столбцами firstname и lastname.

  1. firstname, столбец содержит D'Arch
  2. Lastname столбец содержит O'Neil

, и у меня есть индекс, объединяющий столбцы firstname и lastname, и я использую CONTAINS (firstname, '%'|| 'D''A' ||'%') >0

Oracle Query is

select * 
from test 
where CONTAINS (firstname, '%'|| 'D''Ar' ||'%') >0

Но набор результатов пуст.Ключевые слова Oracle Like и instr работают нормально, но я не хочу менять существующую реализацию.

Любые предложения по этой проблеме.

1 Ответ

0 голосов
/ 13 декабря 2018

Предположим, что эти примеры данных - см. Ниже инструкцию CTAS для их создания.

FIRSTNAME LASTNAME
--------- --------
D'Arch    O'Neil   
DArch     ONeil    
D Arch    O Neil   
D.Arch    O.Neil 

Чтобы сохранить апостроф, вы должны определить его как printjoin персонаж.В противном случае он будет удален в процессе токенизации (сравните с точкой в ​​последней строке).

BEGIN
  ctxsys.ctx_ddl.create_preference('lex', 'BASIC_LEXER');
  ctxsys.ctx_ddl.set_attribute('lex', 'printjoins', '''');  
END;
/
---
BEGIN
  ctxsys.ctx_ddl.create_preference('pref', 'MULTI_COLUMN_DATASTORE');
  ctx_ddl.set_attribute('pref', 'columns', 'firstname, lastname');
END;
/

create index idx_test on test(firstname)
indextype is CTXSYS.CONTEXT
parameters ('datastore  pref LEXER  lex')
;

Лучший способ увидеть токены результата после создания индекса - запросить таблицу $I,который содержит все токены:

select TOKEN_TEXT from DR$IDX_TEST$I;

TOKEN_TEXT                                                     
----------------------------------------------------------------
ARCH                                                             
D'ARCH                                                           
DARCH                                                            
FIRSTNAME                                                        
LASTNAME                                                         
NEIL                                                             
O                                                                
O'NEIL                                                           
ONEIL                                                            

Итак, как и ожидалось, точка исчезает, но апостроф выжил.

Теперь вы можете запросить и получите ожидаемый результат:

select * 
from test 
where CONTAINS (firstname, '%D''Ar%') >0;

FIRSTNAME LASTNAME
--------- --------
D'Arch    O'Neil 

Конечно, поскольку вы используете MULTI_COLUMN_DATASTORE, вы также можете запросить данные из столбца lastname.

select * 
from test 
where CONTAINS (firstname, '%O''Ne%') >0;

FIRSTNAME LASTNAME
--------- --------
D'Arch    O'Neil

Пример данных

create table test as
select 'D''Arch' firstname, 'O''Neil' Lastname from dual union all
select 'DArch' firstname, 'ONeil' Lastname from dual union all
select 'D Arch' firstname, 'O Neil' Lastname from dual union all
select 'D.Arch' firstname, 'O.Neil' Lastname from dual;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...