Как конвертировать колекциию SQL типа в колекцию PL/SQL типа без циклов?
Пытаюсь конвертировать колекцию SQL типа в колекцию PL/SQL типа (или наоборот).
create or replace type arrayforvarchar as table of varchar2(30);
/
Пробую как в этом анонимном блоке
declare
type arrayforvarcharplsql is table of varchar2(30);
var_plsql_array arrayforvarcharplsql;
var_sql_array arrayforvarchar := arrayforvarchar();
begin
select cola
bulk collect into var_plsql_array
FROM (
select 'X' as cola from dual
union all
select 'Y' as cola from dual);
--var_sql_array := var_plsql_array
end;
/
Но простое присвоение одной коллекции к другой не работает.
Как можно присвоить заначения var_plsql_array к var_sql_array без использования циклов?
Свободный перевод вопроса Oracle Converting SQL type to PLSQL collection / Oracle converting one collection type to another от участника @sakeesh
Ответы (1 шт):
Нет, без циклов невозможо преобразовать кoллекцию одного типа в коллекцию другого типа.
Пдробнее в подглаве Assigning Values to Collection Variables:
Data Type Compatibility
You can assign a collection to a collection variable only if they have the same data type.
Having the same element type is not enough.
Даже если обе эти коллекции объявлены в PL/SQL, так не будет работать:
declare
type t1 is table of int;
type t2 is table of int;
a t1 := t1 (1);
b t2;
begin b := a;
end;
/
ORA-06550: line 6, column 12:
PLS-00382: expression is of wrong type
Нет никакой внутренней функции вроде CAST для преобразвания кoллекции одного типа к коллекции другого типа. Хотя можно использовать свою собственную функцию чтобы скрыть цикл. Воспроизводимый пример:
create or replace type arrsql as table of varchar2 (30);
/
var rc refcursor
declare
type arrpls is table of varchar2(30);
source arrpls := arrpls ('aaa','bbb','ccc');
target arrsql;
function cast (s arrpls, astypeof arrsql) return arrsql is
t arrsql := arrsql ();
begin
t.extend (s.count);
for i in 1..s.count loop t(i) := s(i); end loop;
return t;
end;
begin
target := cast (source, astypeof=>target);
open :rc for select * from table (target);
end;
/
Result Sequence
------------------------------
aaa
bbb
ccc
В релизе 20c появится более лаконичня форма FOR цикла. Тогда преобразование типов коллекций можнно будет написаать проще:
declare
type arrpls is table of varchar2 (30);
arr arrpls := arrpls ('aaa','bbb','ccc');
res arrpls;
begin
res := arrpls (for i,v in pairs of arr index i => v);
end;
/