Как я могу удалить вложенные таблицы в запросе? - PullRequest
2 голосов
/ 16 февраля 2011

У меня есть процедура, которая принимает входные данные, аналогичные parent_arr, показанным ниже, в качестве входных данных от уровня приложения через ODP.Net. На первом этапе процедуры я сохраняю данные из массива во глобальной временной таблице, чтобы я мог выполнить несколько следующих шагов, используя логику установки, а не циклы pl / sql. Пока в массиве есть только один член parent_typ, все в порядке. Однако, когда существует более одного члена, я получаю ORA-01427, запрос одной строки возвращает более одной строки. Запрос ниже возвращает две коллекции. Мне нужно развернуть обе коллекции в одном SQL-выражении, которое будет отображать child.name и child.value. Как это можно сделать?

Образцы объектов

create type child_typ is object( name varchar2(100), value number );
create type child_arr is table of dropme_child_typ;
create type parent_typ is object( pname varchar2(100), child dropme_child_arr );
create type parent_arr is table of dropme_parent_typ;

При запросе ниже будет выброшено ORA-01427

select * from table(
    select child
    from table( parent_arr(
        parent_typ( 'TEST1',
            child_arr(
                child_typ( 'C1', 1 ),
                child_typ( 'C2', 2 ) ) ),
        parent_typ( 'TEST2',
            child_arr(
                child_typ( 'C3', 3 ),
                child_typ( 'C4', 4 ) ) ) ) ) );

Этот запрос работает, но возвращает столбец объекта child_arr

select child
from table( parent_arr(
    parent_typ( 'TEST1',
        child_arr(
            child_typ( 'C1', 1 ),
            child_typ( 'C2', 2 ) ) ),
    parent_typ( 'TEST2',
        child_arr(
            child_typ( 'C3', 3 ),
            child_typ( 'C4', 4 ) ) ) ) );

Этот запрос не выполнен, потому что я не могу получить доступ к значениям в "child"

select child.name, child.value from
 table( parent_arr(
     parent_typ( 'TEST1',
         child_arr(
             child_typ( 'C1', 1 ),
             child_typ( 'C2', 2 ) ) ),
     parent_typ( 'TEST2',
         child_arr(
             child_typ( 'C3', 3 ),
             child_typ( 'C4', 4 ) ) ) ) );

Пожалуйста, скажите мне, что есть способ сделать это без использования цикла pl / sql (это единственный способ, которым я смог добиться успеха до сих пор). Скорость имеет первостепенное значение. Я попытался использовать оператор forall, чтобы пройтись по элементам parent_arr, но он выдает большую ошибку в привязке.

1 Ответ

1 голос
/ 16 февраля 2011

Вы можете использовать боковое соединение , чтобы удалить вложенный дочерний объект:

SQL> WITH my_data AS (
  2     SELECT pname, child
  3       FROM TABLE(parent_arr(parent_typ('TEST1',
  4                                        child_arr(child_typ('C1', 1),
  5                                                  child_typ('C2', 2))),
  6                             parent_typ('TEST2',
  7                                        child_arr(child_typ('C3', 3),
  8                                                  child_typ('C4', 4)))))
  9  )
 10  SELECT my_data.pname, child.name, child.value
 11    FROM my_data, table(my_data.child) child;

PNAME    NAME       VALUE
-------- ----- ----------
TEST1    C1             1
TEST1    C2             2
TEST2    C3             3
TEST2    C4             4

Это форма внешнего объединения, где вы присоединяете родителя с его дочерними элементами.

...