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

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

19 июн. 2018 г.

Разбиение строки на токены

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


with
    q_item_list as (
        select 'a,b,cv,d,r,e,,df,f,' list, ',' delimiter, '''' quotation 
        from dual),
    q_item_list_prepared as (
        select quotation||replace(list, delimiter, quotation||delimiter||quotation)||quotation list, delimiter, quotation 
        from q_item_list)
select
    regexp_substr(list, '['||quotation||']([^'||delimiter||']*)['||quotation||']+',1,level,'mi',1)
from
    q_item_list_prepared
connect by
    regexp_substr(list, '[^'||delimiter||']+',1,level) is not null

В данном случае строкой, имитирующей список является строка  'a,b,cv,d,r,e,,df,f,' (см q_item_list), разделителем я выбрал запятую, а обрамляющим символом принимается одиночный апостроф.
Первым делом квотируем все элементы списка апострофами с обеих сторон, чтобы не потерять при разбиении пустые элементы (см. q_item_list_prepared). После этого спокойно нарезаем все элементы по разделителю и после этого удаляем обрамляющие символы.

Если перед нами стоит задача получить из этой строки только непустые элементы, то все резко упрощается:

with
    q_item_list as (
        select 
            'a,b,cv,d,r,e,,df,f,' list, ',' delimiter, '''' quotation 
        from 
            dual)
    select 
        regexp_substr(list, '[^'||delimiter||']+',1,level) 
    from 
        q_item_list 
    connect by 
        regexp_substr(list, '[^'||delimiter||']+',1,level) is not null

В данном запросе мы ничего не подготавливаем к нарезке, а просто режем строку по разделителю.