Поне загубихте дефиниция на таблица във втория случай. Това твърдение:
create or replace TYPE tbl_list2 IS OBJECT (l_owner VARCHAR2(64),l_name VARCHAR2(64));
декларира само тип обект (или запис), а не таблица.
Така че трябва да го направите в 2 стъпки:
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;
/
След това се нуждаете от някои корекции на синтаксиса в скрипта:
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;
/
АКТУАЛИЗАЦИЯ
Горното решение е относително бавно поради големия брой превключвания на контекста. Но сравнението на екземпляри на сложни типове обекти не може да се направи директно в PL/SQL без допълнителна работа.
За да позволим на Oracle да знае дали екземплярите на обекти са еднакви или различни, трябва да дефинираме метод за картографиране или подреждане за тип обект
. И двата вида методи не са разрешени, така че трябва да изберете правилния. Методите на MAP се изпълняват по-бързо и в нашия случай няма нужда от поръчка, така че действайте:
create or replace TYPE tbl_list_rec2 AS OBJECT (
l_owner VARCHAR2(64),
l_name VARCHAR2(64),
map member function get_key return varchar2
);
/
Внедряване:
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;
/
След това е възможно да се тестват обекти за равенство в PL/SQL код като прост varchar2
в първия пример от въпроса:
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;
/