2011-09-16 24 views
6

Necesito recopilar una gran cantidad de identificadores de un par de tablas diferentes en una variable de algún tipo para pasar a otra función. De qué tablas tomar los identificadores es dinámico, dependiendo del parámetro iVar a continuación. La pregunta es si no hay una mejor manera de hacerlo ya que este enfoque tendrá que copiar y volver a asignar los arrays varias veces. ¿Sería mejor insertarlo todo en una tabla temporal? ¿Sería mejor usar sql dinámico? Véase la función get_ids a continuación:Colecciones de concatenación en PLSQL

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; 

Respuesta

4

Resulta que hay una manera mucho más simple para concatenar: (.. El crédito a https://forums.oracle.com/forums/thread.jspa?messageID=7420028 no tenía idea de que esto era posible hasta hoy)

iList1 MULTISET UNION ALL iList2 

+5

El ALL es opcional. MULTISET UNION no filtra las entradas de ninguna manera. – APC

+0

debería haber sido "no ordena OR filtro" 8-) – APC

8

Si está utilizando 10g o temprano puede hacer que el CONCAT() de un poco más eficiente mediante el operador UNION MULTISET:

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; 
.210

Se podría hacer las cosas más eficientes poblando varias matrices diferentes y luego llamar MULTISET UNIÓN una vez para todos ellos:

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

El uso de SQL dinámico - presumiblemente para sustituir a los distintos get_idsN() funciones - podría ser un enfoque pena investigar , pero probablemente no le dará mucho, en todo caso, en cuanto a un mejor rendimiento.

Las tablas temporales no son una buena idea, ya que funcionan muy mal en comparación con hacer cosas en la memoria.