我创建了一个返回表的流水线函数。我使用这个函数就像在另一个函数中的动态视图一样,在一个with
子句中,来标记某些记录。然后,我根据各种条件在聚合查询中使用此查询的结果。我想要做的是union all
这些聚合在一起(因为它们都使用相同的源数据,但在不同的层次结构级别显示聚合)。
当我为各个级别生成数据时,它工作正常。但是,当我尝试组合它们时,我收到 ORA-12840 错误:cannot access a remote table after parallel/insert direct load txn
.
(我应该注意,我的函数和查询是通过数据库链接查看远程服务器上的表)。
有什么想法吗?
这是代码的一个想法:
function getMatches(criteria in varchar2) return myTableType pipelined;
...这个函数基本上执行一些动态 SQL,它引用远程表作为引用游标并吐出结果。
然后分解查询类似于:
with marked as (
select id from table(getMatches('OK'))
),
fullStats as (
select mainTable.id,
avg(nvl2(marked.id, 1, 0)) isMarked,
sum(mainTable.val) total
from mainTable
left join marked
on marked.id = mainTable.id
group by mainTable.id
)
第一个因素的原因是速度——如果我在连接中内联它,查询会非常缓慢——但无论哪种方式,它都不会改变任何导致异常的状态。
然后,说一个完整的概述,我会这样做:
select sum(total) grandTotal
from fullStats
...或通过以下方式进行概述isMarked
:
select sum(total) grandTotal
from fullStats
where isMarked = 1
这些单独工作正常(我的伪代码可能错误或过于简单,但你明白了),但只要我union all
把它们放在一起,我就会得到 ORA-12840 错误:(
编辑根据要求,这是我的函数的混淆版本:
function getMatches(
search in varchar2)
return idTable pipelined
as
idRegex varchar2(20) := '(05|10|20|32)\d{3}';
searchSQL varchar2(32767);
type rc is ref cursor;
cCluster rc;
rCluster idTrinity;
BAD_CLUSTER exception;
begin
if regexp_like(search, '^L\d{3}$') then
searchSQL := 'select distinct null id1, id2_link id2, id3_link id3 from anotherSchema.linkTable@my.remote.link where id2 = ''' || search || '''';
elsif regexp_like(search, '^' || idRegex || '(,' || idRegex || || ')*$') then
searchSQL := 'select distinct null id1, id2, id3 from anotherSchema.idTable@my.remote.link where id2 in (' || regexp_replace(search, '(\d{5})', '''\1''') || ')';
else
raise BAD_CLUSTER;
end if;
open cCluster for searchSQL;
loop
fetch cCluster into rCluster;
exit when cCluster%NOTFOUND;
pipe row(rCluster);
end loop;
close cCluster;
return;
exception
when BAD_CLUSTER then
raise_application_error(-20000, 'Invalid Cluster Search');
return;
when others then
raise_application_error(-20999, 'API' || sqlcode || chr(10) || sqlerrm);
return;
end getMatches;
它非常简单,专为对数据库访问受限的 API 设计,就复杂性而言(因此传递一个逗号分隔的字符串作为可能的有效参数):如果您提供分组代码,它会返回链接的 ID(它是复合的,3 -字段键);但是,如果您提供自定义代码列表,它只会返回这些代码。
我在 Oracle 10gR2 上;不确定具体是哪个版本,但我可以在我回到办公室时查看它:P