Au moins, vous avez perdu une définition de table dans le deuxième cas. Cette déclaration :
create or replace TYPE tbl_list2 IS OBJECT (l_owner VARCHAR2(64),l_name VARCHAR2(64));
déclare uniquement le type d'objet (ou d'enregistrement), pas une table.
Vous devez donc le faire en 2 étapes :
create or replace TYPE tbl_list_rec IS OBJECT (l_owner VARCHAR2(64),l_name VARCHAR2(64));
/
create or replace TYPE tbl_list2 as table of tbl_list_rec;
/
Après cela, vous avez besoin de quelques corrections de syntaxe dans le script :
declare
l_object tbl_list2;
i number;
begin
-- for list initialization it must be filled with constructed objects
l_object := tbl_list2( tbl_list_rec('','') );
for i in 1..100000 loop
-- 1. select values to variable
-- 2. Fix constructor for list
select
l_object MULTISET UNION DISTINCT tbl_list2(tbl_list_rec('myOwner','MyTable'))
into
l_object
from
dual;
end loop;
for i in l_object.first .. l_object.last loop
-- output separate fields, there are now default conversion from
-- user-defined objects to varchar2.
dbms_output.put_line(l_object(i).l_owner || ',' || l_object(i).l_name);
end loop;
end;
/
MISE À JOUR
Solution ci-dessus relativement lente en raison du grand nombre de changements de contexte. Mais la comparaison d'instances de types d'objets complexes ne peut pas être effectuée directement en PL/SQL sans un travail supplémentaire.
Pour permettre à Oracle de savoir si les instances d'objets sont identiques ou différentes, nous devons définir Méthode de mappage ou de classement pour le type d'objet
. Les deux types de méthodes ne sont pas autorisés, il est donc nécessaire de choisir la bonne. Les méthodes MAP fonctionnent plus rapidement et il n'est pas nécessaire de commander dans notre cas, alors allez-y :
create or replace TYPE tbl_list_rec2 AS OBJECT (
l_owner VARCHAR2(64),
l_name VARCHAR2(64),
map member function get_key return varchar2
);
/
Mise en œuvre :
create or replace TYPE BODY tbl_list_rec2 AS
map member function get_key return varchar2
is
begin
return l_owner||chr(1)||l_name;
end;
end;
/
Après cela, il est possible de tester l'égalité des objets dans le code PL/SQL comme le simple varchar2
dans le premier exemple de la question :
declare
l_object tbl_list2a;
i number;
begin
l_object := tbl_list2a( tbl_list_rec2('','') );
for i in 1..100000 loop
l_object := l_object MULTISET UNION DISTINCT tbl_list2a(tbl_list_rec2('myOwner','MyTable'));
end loop;
for i in l_object.first.. l_object.last loop
dbms_output.put_line(l_object(i).l_owner || ',' || l_object(i).l_name);
end loop;
end;
/