Oracle 从子查询存储过程分配变量

Oracle 从子查询存储过程分配变量,oracle,stored-procedures,plsql,subquery,oracle-sqldeveloper,Oracle,Stored Procedures,Plsql,Subquery,Oracle Sqldeveloper,我有一个Oracle 11.2.0存储过程,它返回一些输出参数。查询的结果使用从复杂子查询填充的refcursor。我需要将子查询中的记录数作为数字输出参数返回。尝试将计数分配给子查询内的变量时遇到问题。有人能告诉我这在Oracle中是否可行,或者是否有其他方法可以做到这一点。我只需要从存储过程返回数据和数据记录的计数。我不确定如何分配和返回计数,因为查询结果是从子查询select语句返回的。下面是我尝试做的一个例子: p_results OUT sys_refcursor,

我有一个Oracle 11.2.0存储过程,它返回一些输出参数。查询的结果使用从复杂子查询填充的refcursor。我需要将子查询中的记录数作为数字输出参数返回。尝试将计数分配给子查询内的变量时遇到问题。有人能告诉我这在Oracle中是否可行,或者是否有其他方法可以做到这一点。我只需要从存储过程返回数据和数据记录的计数。我不确定如何分配和返回计数,因为查询结果是从子查询select语句返回的。下面是我尝试做的一个例子:

p_results           OUT sys_refcursor,
p_count             OUT NUMBER
OPEN p_results 
FOR 
  WITH Output1 AS
    (
    SELECT * from table1
    ),
output2 AS
    (
    SELECT * from table2 a
    left outer join Output1 b
    on a.id = b.id
     )
    Select * from output2
    p_count := select count(id) from output2   --how can I return parameters for results and count using subquery

你不能做你想做的事。Oracle不知道在获取最后一行之前,游标将返回多少行。由于游标是一个只向前的结构,如果您的目标是将游标返回到调用应用程序,那么您就不能在代码中从它获取数据

您可以重复查询,并分两步执行此操作

SELECT COUNT(id)
  INTO p_count
  FROM (<<your query>>);

OPEN p_results
 FOR <<your query>>;
这将消除两个查询返回不同行数的可能性。但是,这可能会使查询的成本更高,因为Oracle需要在客户端开始从结果集获取数据之前具体化结果集。它可能仍然比两次运行同一查询更有效,除非每行重复的附加数值会增加需要通过网络传输或由客户端缓冲的数据量,从而造成性能问题


一般来说,对于任何同时向调用应用程序返回计数和结果集的设计,我都会非常怀疑。无论如何,调用应用程序都需要代码从游标中提取。如果它有这样的代码,那么它非常适合计算它实际获取的行数,然后对计算结果进行操作。您的过程应该只返回
sys_refcursor
并将计数留给客户端。

是否有任何方法将refcursor存储在一个表变量中以获取计数并仍然从存储过程返回p_结果?@user3397437-我想您可以,声明一个与
select
语句的投影匹配的对象类型(更改代码以便不再执行
select*
操作),声明该对象类型的SQL集合,
bulk collect
将查询中的数据收集到该集合类型的实例中,然后返回计数和查询该集合的结果。这可能会占用大量内存,具体取决于所涉及的数据的大小和数量,但这是可能的。不过,如果有一个全局临时表,可能会更好。
OPEN p_results
 FOR ...
     Select o2.*, count(*) over () cnt 
       from output2 o2