Традиционный поиск и замена в PL/SQL на примерах

Функции INSTR и SUBSTR в PL/SQLДостаточно часто в строке требуется найти заданный фрагмент текста. Начиная с Oracle10g, для подобных манипуляций с текстом могут использоваться регулярные выражения. Если вы еще не перешли на Oracle10g или более позднюю версию, существует решение, совместимое со старыми версиями базы данных. Функция INSTR возвращает позицию подстроки в большей строке. Следующий фрагмент находит позиции всех запятых в списке имен: 

DECLARE
   names VARCHAR2(60) := 'Anna,Matt,Joe,Nathan,Andrew,Aaron,Jeff';
   comma_location NUMBER := 0;
BEGIN
   LOOP
      comma_location := INSTR(names,',',comma_location+1);
      EXIT WHEN comma_location = 0;
      DBMS_OUTPUT.PUT_LINE(comma_location);
   END LOOP;
END;

Результат:

5
10
14
21
28
34

Первый аргумент INSTR содержит строку, в которой проводится поиск. Второй аргумент задает искомую подстроку — в данном случае это запятая. Третий аргумент задает позицию, в которой начинается поиск. После каждой найденной запятой цикл продолжает поиск с символа, следующего за найденным. Если совпадения отсутствуют, INSTR возвращает ноль, и цикл на этом завершается.

Следующий естественный шаг после обнаружения текста в строке — его извлечение. Естественно, нас интересуют не запятые, а те имена, которые они разделяют. Для извлечения строковых данных применяется функция SUBSTR

DECLARE
   names VARCHAR2(60) := 'Anna,Matt,Joe,Nathan,Andrew,Aaron,Jeff';
   names_adjusted VARCHAR2(61);
   comma_location NUMBER := 0;
   prev_location NUMBER := 0;
BEGIN
   -- Включение запятой за последним именем
   names_adjusted := names || ',';
   LOOP
      comma_location := INSTR(names_adjusted,',',comma_location+1);
      EXIT WHEN comma_location = 0;
      DBMS_OUTPUT.PUT_LINE(
      SUBSTR(names_adjusted,
      prev_location+1,
      comma_location-prev_location-1));
      prev_location := comma_location;
   END LOOP;
END;

Программа выдает следующий список имен:

Anna
Matt
Joe
Nathan
Andrew
Aaron
Jeff

В приведенном коде следует обратить внимание на два ключевых момента. Во-первых, в конец строки добавляется запятая, упрощающая реализацию логики цикла. Теперь за каждым именем в names_adjusted следует запятая; это упрощает нашу задачу. Во-вторых, каждый раз, когда цикл доходит до вызова DBMS_OUTPUT.PUT_LINE, в переменных prev_location и comma_location сохраняются позиции символов по обе стороны от выводимого имени. В этом случае все сводится к простым вычислениям и вызову функции SUBSTR, которая получает три аргумента:

  • names_adjusted — строка, из которой извлекается имя;
  • prev_location+1 — позиция первой буквы имени. Вспомните, что в переменной prev_location хранится позиция символа, непосредственно предшествующего выводимому имени (обычно запятой). Эта позиция увеличивается на единицу.
  • comma_location-prev_location-1 — количество извлекаемых символов. Вычитание единицы предотвращает вывод завершающей запятой.

 

Вас заинтересует / Intresting for you:

Управление приложениями PL/SQL...
Управление приложениями PL/SQL... 3112 просмотров Stas Belkov Thu, 16 Jul 2020, 06:20:48
Встроенные методы коллекций PL...
Встроенные методы коллекций PL... 7023 просмотров sepia Tue, 29 Oct 2019, 09:54:01
Символьные функции и аргументы...
Символьные функции и аргументы... 10872 просмотров Анатолий Wed, 23 May 2018, 18:54:01
Тип данных RAW в PL/SQL
Тип данных RAW в PL/SQL 5752 просмотров Doctor Thu, 12 Jul 2018, 08:41:33
Войдите чтобы комментировать

Fasenger аватар
Fasenger ответил в теме #9269 29 окт 2018 03:48
INSTR и SUBSTR - обыденность программиста, пишущего на PL/SQL. Полностью понимать, как работают эти функции, просто необходима. Спасибо за статью и примеры в ней.