Конкатенация коллекций в PLSQL - PullRequest
6 голосов
/ 16 сентября 2011

Мне нужно собрать множество идентификаторов из нескольких разных таблиц в переменную какого-то типа для передачи в другую функцию. Из каких таблиц брать идентификаторы динамические, в зависимости от параметра iVar ниже. Вопрос в том, не существует ли лучшего способа сделать это, так как этот подход должен будет копировать и перераспределять массивы несколько раз. Было бы лучше вставить все это во временную таблицу? Было бы лучше использовать динамический SQL. Смотрите функцию get_ids ниже:

FUNCTION concat (
    iList1 IN ID_ARRAY,
iList2 IN ID_ARRAY
) 
RETURN ID_ARRAY IS
    lConcat ID_ARRAY;
BEGIN
    SELECT column_value BULK COLLECT INTO lConcat FROM (
        (SELECT column_value FROM TABLE(CAST( iList1 AS ID_ARRAY))) 
        UNION ALL 
        (SELECT column_value FROM TABLE(CAST( iList2 AS ID_ARRAY)))
    );
    RETURN lConcat;
END concat;

FUNCTION get_ids (
    iVar           IN NUMBER
) 
RETURN ID_ID_ARRAY IS
    lIds ID_ARRAY;
BEGIN
    lids := get_ids0();
    IF iVar = 1 THEN
        lIds := concat(lFilter, get_ids1());
    ELSE
        lIds := concat(lFilter, get_ids3());
        IF iVar = 4 THEN
            lIds := concat(lFilter, get_ids4());
        END IF;
    END IF;
    RETURN lIds;
END get_ids;

Ответы [ 2 ]

8 голосов
/ 16 сентября 2011

Если вы используете 10g или более позднюю версию, вы можете сделать функцию CONCAT () несколько более эффективной, используя оператор MULTISET UNION:

FUNCTION concat (
    iList1 IN ID_ARRAY,
      iList2 IN ID_ARRAY
) 
RETURN ID_ARRAY IS
    lConcat ID_ARRAY;
BEGIN
    lConcat := iList1 
               MULTISET UNION  
               iList2 A
    ;
    RETURN lConcat;
END concat;

Вы можете сделать вещи более эффективными, заполнив несколько различных массивов изатем вызов MULTISET UNION один раз для всех из них:

   lConcat := iList1 
               MULTISET UNION  
               iList2  
               MULTISET UNION  
               iList3
               MULTISET UNION  
               iList4;  

Использование динамического SQL - предположительно для замены различных get_idsN() функций - может оказаться подходящим вариантом для изучения, но, вероятно, не даст вам много, есличто угодно, на пути улучшения производительности.

Временные таблицы не очень хорошая идея, потому что они работают очень плохо по сравнению с работой в памяти.

4 голосов
/ 16 сентября 2011

Оказывается, есть гораздо более простой способ объединения:

iList1 MULTISET UNION ALL iList2

(Кредит https://forums.oracle.com/forums/thread.jspa?messageID=7420028. Я даже не подозревал, что это возможно до сегодняшнего дня.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...