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

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

12 дек. 2024 г.

Передача списка значений в качестве значения переменной в процедуру PL/SQL из клиентского приложения

    Когда я только начинал писать на Java и C#, то всегда мучался с выдумыванием различных вариантов для передачи списков в процедуры PL/SQL из клиентского слоя. Понятное дело, что на уровне клиента всегда несоизмеримо проще сформировать некий документ в транспортабельном формате, чтобы потом обработать его в БД, для этого очевидно можно и нужно использовать готовые форматы XML или JSON, не выдумывая ненужных велосипедов, но принципы эффективного парсинга сформированных таким образом документов не всегда очевидны. 

    Со временем у меня сформировалась и устоялась некоторая технология, которая дает возможность неплохо унифицировать работу с различными наборами параметров при их формировании и при обработке на уровне PL/SQL. Собственно сложность в основном заключается в парсинге переданных значений на уровне PL/SQL. Именно поэтому я изначально и уделяю достаточно много времени тому, чтобы эффективно разбивать переданные строки на значения без выполнения сложных операций строковой обработки

Вот достаточно простой пример. Передача некоего списка значений в процедуру, где каждое из передаваемых значений является объектом (т. е. имеет свой собственный набор атрибутов помимо значения, например порядковый номер или что-то подобное). Задачу имеет смысл разбить на несколько этапов:

1 этап - сериализация списка в xml формат на уровне клиента, выполняется достаточно просто за счет использования базовых интерфейсов в используемом языке

2 этап - передача значения в параметр процедуры. Тут возникает только один вопрос, какой тип использовать для передачи параметра. Как правило я использую varchar2 параметры для передачи небольших списков и CLOB параметры, если длина списка непредсказуема либо точно превышает 4000 байт

3 этап - парсинг переданного списка в PL/SQL. Как вариант, можно использовать встроенную поддержку XML 

with q_xml as (
select 
        xmltype('<ordering>
            <person id = "1" checkout="1799-12-01">George Washington</person>
            <person id = "2" checkout="1826-12-01">John Adams</person>
            <person id = "3" checkout="1826-12-01">Tomas Jefferson</person>
            <person id = "4" checkout="1836-12-01">James Medisson</person>
            <person id = "5" checkout="1831-12-24">James Monroe</person>
        </ordering>') xml_data from dual
    )
select xt.id, xt.val, xt.checkout
from 
    q_xml x, 
    XMLTABLE('/ordering/person'
             PASSING x.xml_data
             COLUMNS 
               val     VARCHAR2(4000)  PATH '.',
               id     number  PATH '@id',
               checkout     date  PATH '@checkout'
             ) xt

Таким образом, на уровне SQL можно оперировать результирующим набором, сформированным на клиенте, если драйвер не имеет поддержки передачи массивов, например если вы работаете с драйвером ADODB.NET или любым другим драйвером с урезанным функционалом 

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