Блог СУБД SoQoL

Найди три отличия

Часто функции, выполняющие одинаковые действия и дающие схожий результат, имеют в разных СУБД если не одинаковые имена, то очень похожие. Но только не в этот раз

Данная функция работает со строковыми типами данных и позволяет найти позицию первого или определённого по счёту вхождения подстроки в исходной строке. Но функции, выполняющие схожие операции, в разных СУБД имеют своё имя… давайте разбираться кто-где-кто

Начнём с PostgreSQL
В этой СУБД функция носит имя POSITION и принимает два аргумента:
▪️ исходную строку;
▪️ подстроку.
Возвращает POSITION позицию первого вхождения подстроки в исходную строку или 0, если подстрока не найдена. Начальная позиция, с которой начинается поиск, всегда первая и изменить её нельзя.

Краткий пример:
SELECT POSITION('lo' IN 'hello world'); -- результат: 4

MS SQL
Здесь мы видим функцию CHARINDEX, которая схожа с POSITION в Postgres и также принимает два аргумента - исходную строку и подстроку.
CHARINDEX возвращает позицию первого вхождения подстроки в исходную строку или 0, если подстрока не найдена. И она также как POSITION в Postgres не позволяет задать начальную позицию для поиска.

Oracle
Здесь это функция носит имя INSTR. Но она отличается от вышеупомянутых функций тем, что принимает четыре аргумента:
▪️ исходную строку;
▪️ подстроку;
▪️ начальную позицию для поиска;
▪️ номер вхождения

INSTR возвращает позицию первого или указанного по счёту вхождения подстроки в исходную строку, или 0 если подстрока не найдена. Если начальная позиция не указана, то по умолчанию поиск начинается с позиции 1.

Краткий пример:
SELECT INSTR('hello world', 'lo') FROM dual; -- результа: 4

Перед реализацией данного функционала в СУБД SoQoL мы проанализировали схожие функции в популярных СУБД. POSITION в Postgres и CHARINDEX в MS SQL не позволяют задать, например, начальную позицию для поиска или номер вхождения. Наиболее полной нам показалась реализация в Oracle. Поэтому мы позаимствовали его вместе с наименованием функции.

Итак, СУБД SoQoL
У нас реализована функция INSTR, которая:
1. Принимает два обязательных аргумента (исходную строку, подстроку) и два необязательных (начальную позицию для поиска, номер вхождения).
2. Возвращает позицию первого или указанного по счёту вхождения подстроки в исходную строку, или 0 если подстрока не найдена.
3. Если значение номера вхождения не задано, то по умолчанию равно 1.
4. Если начальная позиция не указана, то по умолчанию поиск начинается с позиции 1.

Значение строки и подстроки могут быть значениями типа:
▪️ CHAR, VARCHAR;
▪️ NUMBER, BOOLEAN, DATE, TIMESTAMP, BINARY, VARBINARY, ROWID. В этом случае будет выполнена попытка приведения значения аргумента к значению типа VARCHAR.

Над возможностью использования значение типа CLOB в строке и подстроке нам предстоит еще поработать в недалеком будущем.

Значения аргумента номера символа и номер вхождения задаются целым числом. Если указано дробное число, то функция усечёт его до целого числа. Если задать значение в типе CHAR, VARCHAR, то будет попытка преобразования к типу NUMBER.

Посмотрим работу функции на шуточных, но наглядных примерах:

select instr ('АаааАА, кричал сисадмин', 'а');
Результат: 2

select instr ('АаааАА, кричал сисадмин', 'аа', 1, 2);
Результат: 3

select instr ('аааААаа, кричал сисадмин, АА', 'АА', -3, 1);
Результат: 4

select instr ('аааАА, кричал сисадмин', 'дас', -3, 1);
Результат: 0

Обсудить в телеграме!