Oracle
 sql >> Base de données >  >> RDS >> Oracle

Manipulation des collections

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;
/