Местоположение искомых элементов текста

Функция

Предоставление списка позиций (местоположения) заданных элементов текстовых данных. Под элементом текста (словом) понимается любая последовательность символов, включающая только буквы, цифры, подчеркивание и дефис. Все остальные символы считаются разделителями.

Спецификация
 
< поисковое выражение >::=
< шаблон поиска >::=
< LIKE-шаблон >::=
< CONTAINS-шаблон >::=
< тип поиска >::=
1 | 2 | 5 |6
< начало поиска >::=
< объём поиска >::=
Синтаксические правила
  1. < Имя столбца > должно соответствовать столбцу типа BLOB, EXTFILE, CHAR, VARCHAR, NCHAR, NCHAR VARYING.

  2. < LIKE-шаблон > должен соответствовать спецификации < предиката подобия > (см. пункт «Предикат подобия») и может содержать стандартные специальные символы: подчеркивание «_» представляет собой указатель на произвольный символ, процент «%» – указатель на подстроку (возможно, пустую).

    create or replace table test(c char(100));
    insert into test(c) values ('11 22 333 11 4411 55 666 1177 811 1199');
    select gettextpos(c,'11%',2,1,2) from test;
    |0000000002 0000000013 1 2 11 2|  
    select gettextpos(c,'11%|22|4%',2,1,10) from test;
    |0000000006 0000000000 1 2 4 2 11 2 14 4 26 4 35 4|
  3. Следует учитывать различие между шаблоном подобия в < предикате подобия > и в < LIKE-шаблоне > данной функции. В < предикате подобия > шаблон подобия распространяется на весь массив символов указанного столбца, в то время как в данной функции он распространяется только на отдельные элементы текста (слова), например:

    create or replace table tst (c varchar(500));
    insert into tst(c) values ('_11_');
    insert into tst(c) values ('_11 aa_');
    insert into tst(c) values ('_11aa_');
    При выполнении этого запроса находим все 3 записи:
    select rowid from tst where c like '_11%_';
    1
    2
    3
    При выполнении нижеследующего запроса находим заданные элементы текста (слова)
    только в 1 и 3 строках, т.к. во второй строке набор символов '_11 aa_'
    рассматривается функцией GetTextPos как два разных элемента текста (два слова),
    каждый из которых не удовлетворяет шаблону поиска _11%_:
    
    select gettextpos(c, '_11%_',2,1,length(c)) from tst;
    
    |0000000001 0000000000 1 4                       |
    |0000000000 0000000000                           |
    |0000000001 0000000000 1 6                       |
    

  4. < CONTAINS-шаблон > должен соответствовать спецификации < предиката фразового поиска > (см. документ «СУБД ЛИНТЕР. Полнотекстовый поиск в базе данных», пункт «Местоположение искомых элементов текста во внешнем файле») со следующими ограничениям: < поисковое выражение > не должно содержать логических условий («и», «или», «не равно», расстояние между искомыми словами и т.п.).

    select gettextpos(c,'11*',1,1,10) from test;
    |0000000004 0000000000 1 2 11 2 26 4 35 4|

    Длина обоих шаблонов должна быть не больше 64 символов (иначе шаблон поиска усекается до 64 символов).

  5. Если одновременно указывается несколько шаблонов поиска, то все они должны быть однотипными (либо только < LIKE-шаблоны >, либо < CONTAINS-шаблоны >).

  6. < Тип поиска > это битовая маска, задающая атрибуты поиска:

    • 1 (001) – поиск по < CONTAINS-шаблону >;

    • 2 (010) – поиск по < LIKE-шаблону >;

    Значение 4 (100) – поиск с учетом регистра (обязательно объединение с одним из двух предыдущих атрибутов), т.е. < тип поиска > может так же принимать значения:

    • 5 (101) – поиск по < CONTAINS-шаблону > с учетом регистра;

    • 6 (110) – поиск по < LIKE-шаблону > с учетом регистра.

    Из двух флагов-атрибутов CONTAINS (1) и LIKE (2) обязательно должен быть установлен ровно один.

  7. Если < тип поиска > не задан, по умолчанию используется значение 1 (поиск по < CONTAINS-шаблону >), и в этом случае последующие аргументы функции не должны задаваться (будут использованы их значения по умолчанию).

    Конструкция

    select gettextpos(c,'11*') from test;

    эквивалента

    select gettextpos(c,'11*',1,1,0) from test;
  8. < Начало поиска > задает номер позиции (значение типа INTEGER) в данных, начиная с которой необходимо выполнять поиск элементов по шаблону. Отсчет позиций начинается с 1. Аргумент необязательный; если не задан, по умолчанию принимается значение 1.

  9. Если < начало поиска > не задано, по умолчанию используется 1 (поиск с начала), и в этом случае последующий аргумент функции не должен задаваться (будет использовано значение по умолчанию).

    Конструкция

    select gettextpos(c,'11*',1) from test;

    эквивалента

    select gettextpos(c,'11*',1,1,0) from test;
  10. < Объем поиска > (значение типа INTEGER) ограничивает количество маркируемых элементов:

    • 0 – маркировать все найденные элементы;

    • n – выполнять прямой поиск; маркировать заданное (n) количество элементов;

    • -n – выполнять обратный поиск; маркировать заданное (n) количество элементов.

    Аргумент необязательный; если не задан, по умолчанию принимается значение 0.

  11. Если аргумент < начало поиска > не задан или имеет значение 1, а значение аргумента < объем поиска > – отрицательное, то поиск выполняется с конца данных.

    create or replace table test(c char(100));
    insert into test(c) values ('25 a11 22 333 11bc 4411 55 666 1177 811 1199');
    
    select gettextpos(c,'11*',1,1,-3) from test;
    |0000000000 0000000000 |
    (искомые элементы текста не найдены)
    
    select gettextpos(c,'11*',1,length(c)/2,-3) from test;
    |0000000001 0000000000 15 4|
    (найден 1 элемент текста 11bc, находящийся на 15 позиции и имеющий длину 4
     символа).
  12. Аргументы < поисковое выражение >, < начало поиска > и < объем поиска > могут быть заданы < SQL-параметром >, который должен содержать спецификацию типа данных параметра.

    create or replace table test(c char(100));
    insert into test(c) values ('11 22 333 11 4411 55 666 1177 811 1199');
    select gettextpos(c,? (char(5)),2, ?(int),? (int)) from test;
    11%
    1
    2
    |0000000002 0000000013 1 2 11 2|

Возвращаемое значение
  1. Тип возвращаемого значения – VARCHAR(2000).

  2. Структура возвращаемой строки:

    < количество >< разделитель >< продолжение поиска >[< описатель элемента >]…
    < описатель элемента >::=
    < разделитель >< позиция элемента >< разделитель >< длина элемента >

    где:

    • < разделитель > – символ пробела;

    • < количество > – количество промаркированных элементов текста. Поле имеет фиксированную длину – 10 символов;

    • < продолжение поиска > – позиция, с которой необходимо продолжать сканирование данных (после последнего выданного маркированного элемента). Поле имеет фиксированную длину – 10 символов. Если сканирование данных выполнено полностью, значение поля будет равно 0;

    • < описатель элемента > – описатель маркированного элемента текста. Элементы описателя имеют парное значение: < позиция элемента > < длина элемента >, которое представляет, соответственно, позицию найденного элемента и его фактическую длину.

create or replace table test(c char(256));
insert into test values ('RELEX is one of the leading Russian application and system software developers');

Запрос осуществляет поиск элементов текста, начинающихся с "develop" (с учетом регистра) или совпадающих с "russian" (без учета регистра).

select gettextpos(c,'#develop*|russian',1,1,0) from test;
| 0000000002 0000000000 29 7 69 10 |

Результат поиска:

найдено 2 элемента текста (< количество > равно 0000000002)

найдены все элементы (< продолжение поиска > равно 0000000000)

первый найденный элемент находится на 29 позиции и имеет длину 7 символов (слово Russian)

второй найденный элемент находится на 69 позиции и имеет длину 10 символов (слово developers).