Как обойти ограничение text_query в 4000 символов в операторе Oracle CONTAINS? - PullRequest
2 голосов
/ 25 июня 2010

В Oracle синтаксис полнотекстового поиска Содержит оператор :

 CONTAINS(
          [schema.]column,
          text_query    VARCHAR2
          [,label       NUMBER]) RETURN NUMBER;

, что означает, что text_query не может быть длиннее 4000 символов или возникнет ошибка. Во многих случаях у меня есть text_query длиннее 4000 символов. Как бы вы, как эксперт Oracle, предложили обойти такое ограничение, если это возможно?

Для дальнейшего разъяснения ситуации, в которой легко достичь 4000, можно указать, что если вы объедините множество Содержит операторы запроса для создания вашего text_query, вполне возможно превысить ограничение в 4000 символов.

Ответы [ 2 ]

4 голосов
/ 25 июня 2010

Предел в 4000 символов не является произвольной границей: это максимальное количество символов VARCHAR2, которое может обработать Oracle SQL.

4000 символов - это лот текста. В английском это около 600 слов, или страница А4, и немного в разумном шрифте. Не так много приложений, о которых я могу подумать, которые требуют поиска таких больших кусков словоблудия. Даже колледжи, проверяющие эссе студентов на плагиат, будут работать не более чем на уровне абзаца.

Однако, если вы действительно столкнулись с ситуацией, когда совпадение по немногим 4000 символам дает ложные срабатывания, все, что вы можете сделать, это разбить строку запроса на куски и выполнить поиск по ним. Это означает, что вы должны использовать PL / SQL:

create or replace function big_search (p_search_text in varchar2) 
    return sys_refcursor
is
    return_value sys_refcursor;
    p_srch1 varchar2(4000);
    p_srch2 varchar2(4000);
begin

    dbms_output.put_line('search_length='||to_char(length(p_search_text)));

    p_srch1 := substr(p_search_text, 1, 4000);
    p_srch2 := substr(p_search_text, 4001, 4000);


    open return_value for 
        select docname
                , (score(1) + score(2))/2 as score
        from t23
        where contains ( text_column, p_srch1 , 1) != 0
        and  contains ( text_column, p_srch2 , 2) != 0;

    return return_value;
end;
/

Если вы заранее не знаете размер текста для поиска, вам понадобится использовать динамический SQL для его сборки. Обратите внимание, что передача пустых условий поиска в CONTAINS () приведет к броску DRG-50901: text query parser syntax error.

3 голосов
/ 28 декабря 2012

Текущая версия теперь поддерживает параметр CLOB

CONTAINS(
     [schema.]column,
     text_query    [VARCHAR2|CLOB]
     [,label       NUMBER])
RETURN NUMBER;

http://docs.oracle.com/cd/B28359_01/text.111/b28304/csql.htm#i997503

...