Записки жертвы высоких технологий

    Здравствуйте! Мой блог посвящен в большей своей части моей профессиональной деятельности на поприще использования технологий ORACLE для разработки баз данных OLTP и OLAP хранилищ данных. В заметках я периодически размещаю разнообразные SQL, PL/SQL и Java скрипты написанные мной и не только мной, ссылки на интересные источники в сети либо другую полезную информацию, которая каким либо образом касается моей работы с замечательными продуктами компании ORACLE.
    Вы можете связаться со мной по контактному емейлу, если у вас есть какие-либо вопросы, связанные с разработкой баз данных на основе продуктов ORACLE, буду рад помочь вам, если это будет в моих силах.

5 дек. 2013 г.

Очередной "шедевр" формирования результирующего набора из строки с разделителями

Ковырялся в коде старого приложения на предмет его анализа и наткнулся на "мощный алгорим", формирующий результирующий набор строк из строки с разделителями, например из такой: "1,2,3,4,5,6,7,8,9,10,a,b,c,d,e,f":

with src as (SELECT ','||'1,2,3,4,5,6,7,8,9,10,a,b,c,d,e,f'||',' str from dual)
select 
level lvl
trim(substr(Src.Str,instr(Src.Str,',',1,level)+chunk, 
instr (Src.Str,',',1,level+1)-instr(Src.Str,',',1,level)-1)) op_num
from 
src
connect by 
rownum<=(length(Src.Str)-length(replace(Src.Str,',')))-1

Код, конечно, работает, но:
1. В этом коде реально неудобно разбираться
2. Этот код не учитывает наличие пробелов или каких-либо "лишних символов" между разделителями, а по идее - должен

Варианты альтернативного исполнения:

1. Конвейерная (pipelined) функция
2. Функция, возвращающая массив
3. Regexp'ы (пример есть у меня в разделе "Сравнение строк по сигнатурам".

PS. Я бы вот так вот написал:

with params as (select '\s*([^,]+)\s*(,|$)' pattern,'1,2,3,4,5,6,7,   8,  9    ,10,,12, a, bb, ccc , dddd' string from dual)
select 
regexp_substr(params.string, params.pattern, 1level'i',1chunk 
from 
params 
connect by
regexp_substr(params.string, params.pattern, 1level'i',1is not null

Комментариев нет: