Re: PL/SQL таблицы.
От: wildwind Россия  
Дата: 22.05.04 14:46
Оценка:
Здравствуйте, SHorrty, Вы писали:

SH>Кто нибудь сталкивался с необходимостью преобразования сложных PL/SQL таблиц в XML — формат?

SH>Какие решения были найдены?
SH>И есть ли в Oracle9i средства формирования XML данных не для результатов выборки, а для данных, находящихся в памяти?

Да, столкнулись недавно. Были рассмотрены многие варианты. В Oracle (9.2) есть следующие способы получить XMLType:
  1. "Вручную": xml := XMLType('<?xml version="1.0" ? <DOC>abc</DOC>');
  2. Из курсора: xml := XMLType(cur);
  3. Через DBMS_XMLGEN. Варианты: из курсора и из текста селекта 'select * from ...'.
  4. Используя DOM API (пакет DBMS_XMLDOM), можно создать документ любой структуры.
  5. Используя функцию SYS_XMLGEN(), можно создать XMLType из экземпляра объектного типа. Опять же, только через select.
  6. Используя SQLX функции: XMLELEMENT(), XMLFOREST(), XMLCONCAT(), XMLAGG(). Достаточно гибко, но тоже через select.
  7. Написать функцию на Java. Там можно использовать весь Java-арсенал.
Пример, демонстрирующий эти подходы (кроме java), прицепил в виде файла (чтобы не загромождать страницу).

После рассмотрения за и против был выбран DBMS_XMLDOM из-за универсальности и обещанного быстродействия (вроде на C писан). Минусы:
  • код получается довольно громоздким и малопонятным;
  • возможны утечки памяти — созданные DOM-документы нужно удалять самостоятельно.

    Проблему произвольной структуры решили так:
      type CND_rec is record (
        c  varchar2(2000),
        n  number,
        d  date
      );
      type CND_array is table of rs_cell_t index by varchar2(64);

    Вот такая таблица и подается на преобразование в XML. Если хотим конвертнуть одну запись, имена полей будут ключами в таблице. Если имеем набор записей, то к имени поля добавляется номер записи. То есть ключ получается вида <name>[:<row#>]. При этом имена полей и количество записей тоже должны быть известны.


    SH>С объектами — понятно + подвязать еще AnyData и все в поряде будет.
    SH>Ок. Это я так понимаю, мы в PIPELINE упираемся...
    SH>А если вернуться к произвольным коллекциям, с типом не хранимым в БД?

    Да, в этом направлении тоже копал... Есть такой трюк: можно создать табличную функцию, возвращающую ANYDATASET. Создается она по-хитрому, только как pipelined и только через интерфейс ODCITable, и может возвращать коллекцию, структура которой соответствует одному из типов, описанных на уровне схемы. То есть, если например имеется 10 вариантов структуры, то для каждого из них надо сделать
    create type Type1 as object ( ... );
    , и при реализации функции указать, что данные пойдут в таком-то формате. Это можно использовать при обратном преобразовании XML->PL/SQL.

    2 All
    В 10g ограничение на тип снято, и там можно генерить совершенно произвольные структуры. Однако способ сделать это в 9i все еще ищется, так что если кто знает, плз...
  •  
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.