2011-09-16 17 views
6

Ho bisogno di raccogliere molti ID da un paio di tabelle diverse in una variabile di qualche tipo da passare ad un'altra funzione. Le tabelle da cui prelevare gli ID sono dinamiche, a seconda del parametro iVar sottostante. La domanda è se non esiste un modo migliore per farlo poiché questo approccio dovrà copiare e allocare più volte gli array. Sarebbe meglio inserire tutto in un tavolo temporaneo? Sarebbe meglio usare dynamic sql. Vedere la funzione get_ids di seguito:Concatenazione di raccolte in 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; 

risposta

4

Si scopre che c'è un modo molto più semplice per concatenare: (.. Credito al https://forums.oracle.com/forums/thread.jspa?messageID=7420028 non avevo idea di questo è stato possibile fino ad oggi)

iList1 MULTISET UNION ALL iList2 

+5

L'ALL è opzionale. MULTISET UNION non filtra le voci in alcun modo. – APC

+0

avrebbe dovuto essere "non ordina OR filter" 8-) – APC

8

Se si utilizza 10g o poi si può fare la CONCAT() Funzione un po 'più efficiente utilizzando l'operatore 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; 

Si potrebbe fare le cose più efficiente popolando più array differenti e quindi chiamando MULTISET UNION una volta per tutti loro:

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

Utilizzando SQL dinamico - presumibilmente per sostituire i vari get_idsN() funzioni - potrebbe essere un approccio pena indagare , ma probabilmente non ti darà molto, semmai, nel modo di migliorare le prestazioni.

Le tabelle temporanee non sono una buona idea, perché funzionano molto male rispetto a fare le cose in memoria.