Разбиение строчного значения на токены по нескольким разделителям в цикле
Есть переменная с типом данных nvarchar(max) содержащая текст:
номер1;текст1/nномер2;текст2/nномерN;текстN/n
Нужно в цикле заполнять переменные значениями номер1,текст1, затем номер2, тескт2 и т.д., чтобы в в каждой итерации цикла передавать их в функцию.
Как можно это сделать?
Ответы (2 шт):
Автор решения: Akina
→ Ссылка
Схематично:
WITH cte (one_fragment, slack)
AS ( SELECT SUBSTR(field, 1, INSTR(field || '\n', '\n') - 1) AS one_fragment,
SUBSTR(field, INSTR(field || '\n', '\n') + 2, LENGTH(field)) AS slack
FROM sourcetable
UNION ALL
SELECT SUBSTR(slack, 1, INSTR(slack || '\n', '\n') - 1),
SUBSTR(slack, INSTR(slack || '\n', '\n') + 2, LENGTH(slack))
FROM cte
WHERE slack IS NOT NULL )
SELECT one_fragment
FROM cte;
Или что-то типа
SELECT REGEXP_SUBSTR(field,'\n', 1, level)
FROM sourcetable
CONNECT BY REGEXP_SUBSTR(field, '\n', 1, level) IS NOT NULL;
Автор решения: 0xdb
→ Ссылка
Рабочее решение на чистом PL/SQL:
declare
str varchar2 (32000) := 'номер1;текст1/nномер2;текст2/n';
pattern constant varchar2 (64) := '(\w+);(\w+)/n';
type pairRow is record (num varchar2 (16), txt varchar2 (16));
pair pairRow;
counter int := 0;
function print (pair pairRow) return varchar2 is begin
return 'pair('||pair.num||','||pair.txt||')';
end;
begin
<<split>> loop counter := counter+1;
exit split when regexp_substr (str, pattern, 1, counter) is null;
pair.num := regexp_substr (str, pattern, 1, counter, null, 1);
pair.txt := regexp_substr (str, pattern, 1, counter, null, 2);
dbms_output.put_line (print (pair));
end loop;
end;
/
Результат:
pair(номер1,текст1)
pair(номер2,текст2)
Можно заменить REGEX_SUBSTR на низкоуровневые SQl функции SUBSTR,INSTR, если обьём данных очень большой и важна производительность.
В любом случае, надо реализовать как функцию, чтобы вызов выглядел как-то так:
myFunc (getPair (str, counter))