Oracle
 sql >> база данни >  >> RDS >> Oracle

Манипулиране на колекции

Поне загубихте дефиниция на таблица във втория случай. Това твърдение:

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. regex за намиране и избягване на двойни точки в Oracle

  2. Ограничението при получаване на blob данни от Oracle

  3. Разделянето на разделен със запетая низ в Oracle не работи

  4. Извикване на PL/SQL процедура с дефиниран от потребителя запис като IN параметър с помощта на JDBC

  5. Кръстосано присъединяване в Oracle