我有一个要求检查游标是否能够从表A中获取一些行。如果是,则别无选择,从表B中提取行。 当前,目前有两个存储过程。 我试图在一个存储过程中做到这一点。 我尝试使用%ROWCOUNT,但在不更改光标位置的情况下不起作用(因为它将返回0)。 问题是我的输出是光标,所以我不想对其进行任何更改。 如果我进行访存,则返回类型已更改也显示错误。 任何想法如何做到这一点,就像创建一个游标一样,以便可以在副本上而不是在输出游标上进行获取和行计数。 伪示例
create or replace PROCEDURE "proc"
(
output OUT SYS_REFCURSOR,
)
.
BEGIN
.
.
OPEN output for select * from A
END
BEGIN
//check if output was empty then
OPEN output for select * from B
.
.
END
更新: 我按照建议做了
....
BEGIN
...
OPEN output for
with
A as (select ...),
,B as (select ...),
,C as (select ...),
,D as (select ...)
select * from A
union
select * from B where not exists(select null from A)
union
select * from C where not exists(select null from B)
union
select * from D where not exists(select null from C)
END;
由于我确定这些表中的任何一个都有数据,因此我也尝试了以下方法
....
BEGIN
...
OPEN output for
with
A as (select ...)
,B as (select ...)
,C as (select ...),
,D as (select ...)
select * from A
union
select * from B
union
select * from C
union
select * from D
END;
但是这给了我错误 错误(64,7):PL / SQL:ORA-01789:查询块的结果列数不正确 这些4的表结构是不同的。因此,他们可能会返回差异列。 如果4个中有3个为空,那么加入会有意义吗?
答案 0 :(得分:0)
最好在同一个游标中实现您的要求,因为它将使用相同的时间点读取一致性:在您的方法中,第二个open
打开游标的时间与第一个游标不同,实际上A和B中的数据已经可以更改。
这种方法更好:
create or replace PROCEDURE "proc"( output OUT SYS_REFCURSOR,...)
....
BEGIN
...
OPEN output for
with
A as (select ...)
,B as (select ...)
select * from A
union all
select * from B where not exists(select null from A)
END;
另一种可能的解决方案是创建流水线表,例如:
create or replace function ... return {collection type} PIPELINED as
...flag boolean := true;
begin
....
for i in (select * from A) loop
flag:=false;
pipe row(...)
end loop;
if flag then
for i in (select * from B) loop
flag:=false;
pipe row(...)
end loop;
end if;
end;
/
但是您可以看到两个查询也在不同的时间打开。