create or replace package pack as
type numtab is table of number;
function gettab return numtab pipelined;
end;
/
create or replace package body pack as
function gettab return numtab pipelined is
begin
for i in 1..3 loop pipe row (i*10);
end loop;
return;
end;
end;
/
select * from pack.gettab();
Result Sequence
---------------
10
20
30
在当地工作。但是通过远程数据库的链接调用相同的函数:
create database link loopback using 'localhost/pdb1';
select * from pack.gettab@loopback()
/
现在会给出相应的错误:
ORA-30626: 不支持远程对象类型的函数/过程参数
您可以绕过该错误,例如,通过在远程数据库上创建一个视图:
create or replace view viewtab as
select * from pack.gettab()
/
select * from viewtab@loopback:
Result Sequence
---------------
10
20
30
create or replace package pack as
type numtab is table of number;
function gettab (val int) return numtab;
end;
/
create or replace package body pack as
function gettab (val int) return numtab is
begin
return numtab (1*val,2*val,3*val);
end;
end;
/
create database link loopback using 'localhost/pdb1';
var rc refcursor
declare
tab pack.numtab@loopback := pack.gettab@loopback(10);
ret pack.numtab := pack.numtab ();
rc sys_refcursor;
begin null;
ret.extend (tab.count);
for i in 1..tab.count loop ret(i) := tab(i); end loop;
open :rc for select * from table (ret);
end;
/
print rc
Result Sequence
---------------
10
20
30
create or replace package packrem as
type rec is record (id int, memo varchar2 (32));
type tab is table of rec;
function gettab (val int) return tab;
end;
/
create or replace package body packrem as
function gettab (val int) return tab is
begin
return tab (
rec (1, 'memo'||1*val),
rec (2, 'memo'||2*val),
rec (3, 'memo'||3*val));
end;
end;
/
本地数据库上的软件包:
create or replace package pack as
type rec is record (id int, memo varchar2 (32));
type tab is table of rec;
function gettab (val int) return tab pipelined;
end;
/
create or replace package body pack as
function gettab (val int) return tab pipelined is
ret packrem.tab@loopback;
begin
ret := packrem.gettab@loopback (val);
for i in 1..ret.count loop
pipe row (rec (ret(i).id, ret(i).memo));
end loop;
return;
end;
end;
/
请求及其结果:
select * from pack.gettab (10);
ID MEMO
---------- --------------------------------
1 memo10
2 memo20
3 memo30
不,这不是原因。原因就在这里:
单个值是内置数据类型。但是,表函数返回用户定义的数据类型。在远程数据库上声明的自定义数据类型在本地数据库上是未知的。即使你在本地声明一个完全相同的数据类型,从 Oracle 的角度来看,这些都是不同的数据类型。
让我们看一个例子:
在当地工作。但是通过远程数据库的链接调用相同的函数:
现在会给出相应的错误:
您可以绕过该错误,例如,通过在远程数据库上创建一个视图:
之前在这个答案中提出的解决方案,尽管它很简单,但有一个严重的缺点 -将参数传递给 view并不容易。
因此,一个更复杂但相当有效的解决方案是留在 PL/SQL 上下文中。在这种情况下,可以通过链接访问远程数据库上包中声明的数据类型。但是,流水线表函数必须转换为常规表函数。
实施示例:
请注意,该示例在相同架构中使用相同的包,但通过链接和本地访问它会导致更多不兼容的数据类型。因此,将一个转换为另一个的循环是:
根据 TC 的意见,另一个例子来实现。
远程数据库上的包:
本地数据库上的软件包:
请求及其结果: