2010-11-29 15 views
1

Comment linéariser une table imbriquée, qui contient elle-même également des tables imbriquées (remarque: les tables internes peuvent être de taille différente). Supposons que j'ai les déclarations de type suivantes:Linéarisation de la table imbriquée Oracle

CREATE OR REPLACE TYPE VECTOR 
IS 
    TABLE OF NUMBER; 

CREATE OR REPLACE TYPE TABLE_OF_VECTOR 
IS 
    TABLE OF VECTOR; 

Et l'extrait suivant de PL/SQL:

DECLARE 
    number_table TABLE_OF_VECTOR; 
    result_vector VECTOR; 
BEGIN 
    number_table := table_of_vector(vector(23, 4, 2222, 22222222), 
    vector(2, 1, 766, 2), vector(2, 1, 5)); 
END; 

Est-il possible que je peux linéariser number_table et stocker toutes ses valeurs dans result_vector comme une liste continue de nombres? Je veux finir avec:

result_vector == vector(23, 4, 2222, 22222222, 2, 1, 766, 2, 2, 1, 5) 

Répondre

5

Il fait, mais ce n'est pas assez.

select cast(collect(b.column_value) as vector) 
from table(table_of_vector(
      vector(23, 4, 2222, 22222222), 
      vector(2, 1, 766, 2), 
      vector(2, 1, 5))) a, 
     table(a.column_value) b; 

donc la table (...) une partie traite la table_of_vector comme une table « régulière » avec une colonne avec le nom « COLUMN_VALUE ». Nous traitons ensuite cela comme une autre table que j'ai appelée B.

L'expression SELECTed prend tous les numéros individuels qui composent les tables 'B' dans la table 'A' et les agrège en une collection (en utilisant COLLECT) . Enfin, je lance explicitement la collection en tant que type VECTOR.

+0

Merci beaucoup, juste le one-liner que je cherchais. – wcmatthysen

+0

Juste comme un problème secondaire: quelle méthode est la meilleure du point de vue des performances (par rapport à la solution de boucle for)? Pour mon œil non averti, celui-ci ressemble à une jointure cartésienne. – wcmatthysen

1
DECLARE 
    number_table TABLE_OF_VECTOR; 
    result_vector VECTOR:=vector(); 
BEGIN 
    number_table := table_of_vector(vector(23, 4, 2222, 22222222), 
    vector(2, 1, 766, 2), vector(2, 1, 5)); 
for i in number_table.first .. number_table.last loop 
    for j in number_table(i).first .. number_table(i).last loop 
    result_vector.extend(); 
    result_vector(result_vector.count):=number_table(i)(j); 
    end loop; 
end loop; 
for i in 1.. result_vector.count loop 
    dbms_output.put_line(result_vector(i)); 
end loop; 
END; 
/
+0

Merci, c'est juste de savoir: est-ce qu'il n'y a aucun moyen de le faire dans un seul select? Comme: select into result_vector ... L'idéal pour moi serait que Oracle ait un mécanisme interne pour le faire. Cela ressemble presque à un non-collecte (et remballage) pour moi. Je ne sais pas si Oracle supporte cela. – wcmatthysen