尝试将SQL类型集合转换为PLSQL类型。
-- create an SQL type
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
);
end;
/
除了使用循环外,如何将var_plsql_array
的值分配给var_sql_array
?
无论如何,简单分配都不起作用。
答案 0 :(得分:3)
不是我能找到:
由于数组具有不同的类型,因此无法使用简单的分配:
declare
type arrayforvarcharplsql is table of varchar2(30);
var_plsql_array arrayforvarcharplsql;
var_sql_array arrayforvarchar;
begin
var_plsql_array := arrayforvarcharplsql( 'X', 'Y' );
var_sql_array := var_plsql_array;
end;
/
输出:
ORA-06550: line 8, column 22: PLS-00382: expression is of wrong type ORA-06550: line 8, column 5: PL/SQL: Statement ignored
尝试使用CAST
在PL / SQL范围内不起作用,因为它仅在SQL范围内起作用:
declare
type arrayforvarcharplsql is table of varchar2(30);
var_plsql_array arrayforvarcharplsql;
var_sql_array arrayforvarchar;
begin
var_plsql_array := arrayforvarcharplsql( 'X', 'Y' );
var_sql_array := CAST( var_plsql_array AS arrayforvarchar );
end;
/
输出:
ORA-06550: line 8, column 22: PLS-00204: function or pseudo-column '' may be used inside a SQL statement only ORA-06550: line 8, column 5: PL/SQL: Statement ignored
尝试将PL / SQL集合传递到SQL范围以能够使用CAST
无效,因为不能在SQL范围中使用PL / SQL集合:
declare
type arrayforvarcharplsql is table of varchar2(30);
var_plsql_array arrayforvarcharplsql;
var_sql_array arrayforvarchar;
begin
var_plsql_array := arrayforvarcharplsql( 'X', 'Y' );
SELECT CAST( var_plsql_array AS arrayforvarchar )
INTO var_sql_array
FROM DUAL;
end;
/
输出:
ORA-06550: line 8, column 18: PLS-00642: local collection types not allowed in SQL statements
由于与上一个原因相同,尝试将PL / SQL集合传递到SQL范围内的表集合表达式中并使用BULK COLLECT
无效:
declare
type arrayforvarcharplsql is table of varchar2(30);
var_plsql_array arrayforvarcharplsql;
var_sql_array arrayforvarchar;
begin
var_plsql_array := arrayforvarcharplsql( 'X', 'Y' );
SELECT COLUMN_VALUE
BULK COLLECT INTO var_sql_array
FROM TABLE( var_plsql_array );
end;
/
输出:
ORA-06550: line 10, column 19: PLS-00642: local collection types not allowed in SQL statements ORA-06550: line 10, column 12: PL/SQL: ORA-22905: cannot access rows from a non-nested table item ORA-06550: line 8, column 5: PL/SQL: SQL Statement ignored
但是,使用循环并分别分配值确实可以:
declare
type arrayforvarcharplsql is table of varchar2(30);
var_plsql_array arrayforvarcharplsql;
var_sql_array arrayforvarchar;
begin
var_plsql_array := arrayforvarcharplsql( 'X', 'Y' );
var_sql_array := arrayforvarchar();
var_sql_array.EXTEND( var_plsql_array.COUNT );
FOR i IN 1 .. var_plsql_array.COUNT LOOP
var_sql_array(i) := var_plsql_array(i);
END LOOP;
end;
/
db <>提琴here
答案 1 :(得分:3)
否,如果不使用循环,则无法将一种收集类型的值分配给另一种收集类型。参见Assigning Values to Collection Variables:
数据类型兼容性
仅当集合变量具有相同的数据类型时,才可以将它们分配给集合变量。
拥有相同的元素类型是不够的。
即使在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
这样的内部函数可以将一种类型的集合转换为另一种类型的集合。尽管您可以使用自己的函数来隐藏循环。可重现的示例:
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