C'est très facile si vous utilisez PL/SQL comme SQL et non comme d'autres langages. C'est assez spécifique et parfois très agréable justement à cause de ça.
Parfois, je déteste vraiment PL/SQL, mais ce cas est absolument une question d'amour.
Voyez comme c'est facile :
create type it as object (
iter number,
stringval varchar2(100),
intval integer
);
create type t_it as table of it;
declare
t t_it := new t_it();
tmp1 varchar2(32767);
tmp2 varchar2(32767);
begin
t.extend(4);
t(1) := new it(1,'Oslo',40);
t(2) := new it(2,'Berlin',74);
t(3) := new it(3,'Rome',25);
t(4) := new it(4,'Paris',10);
select listagg(stringval,', ') within group (order by stringval),
listagg(stringval,', ') within group (order by intval)
into tmp1, tmp2
from table(t);
dbms_output.put_line(tmp1);
dbms_output.put_line(tmp2);
end;
/
drop type t_it;
drop type it;
Ici, vous pouvez voir le problème que vous devez créer des types globaux, et c'est pourquoi je le déteste. Mais ils disent que dans Oracle 12, cela peut être fait avec des types définis localement, donc je l'attends :)
La sortie est :
Berlin, Oslo, Paris, Rome
Paris, Rome, Oslo, Berlin
MODIFIER
Tant que vous ne connaissez pas le nombre d'itérations depuis le début, le seul moyen est de faire une extension à chaque itération (ce n'est qu'un exemple d'extension) :
declare
iterator pls_integer := 1;
begin
/* some type of loop*/ loop
t.extend();
-- one way to assign
t(t.last) := new it(1,'Oslo',40);
-- another way is to use some integer iterator
t(iterator) := new it(1,'Oslo',40);
iterator := iterator + 1;
end loop;
end;
Je préfère la deuxième méthode car elle est plus rapide (ne calcule pas .last
à chaque itération).