Plsql PL/SQL中refcursor的概念

Plsql PL/SQL中refcursor的概念,plsql,oracle-sqldeveloper,plsqldeveloper,toad,Plsql,Oracle Sqldeveloper,Plsqldeveloper,Toad,嗨,我只是想知道关于refcursor的事。我创建了一个包,如下所示- 创建或替换包体应用程序。emp_pay_pkg 是 奇怪的是,我在另一个使用ref cursor的包上使用了类似的concpet,但为此,我的一位同事告诉我,如果您获取curdor并将其移动到包体中的变量中,那么光标将变为空,因此不应循环并移动到匿名块中的变量中 在这里的某个地方,我认为它应该也适用于上述包。有人能澄清我的想法吗?我不太确定我是否完全理解你的要求 游标本质上是指向可执行以返回结果的程序的指针。它是一个只向前的

嗨,我只是想知道关于refcursor的事。我创建了一个包,如下所示- 创建或替换包体应用程序。emp_pay_pkg 是

奇怪的是,我在另一个使用ref cursor的包上使用了类似的concpet,但为此,我的一位同事告诉我,如果您获取curdor并将其移动到包体中的变量中,那么光标将变为空,因此不应循环并移动到匿名块中的变量中


在这里的某个地方,我认为它应该也适用于上述包。有人能澄清我的想法吗?

我不太确定我是否完全理解你的要求

游标本质上是指向可执行以返回结果的程序的指针。它是一个只向前的结构——您只能获取接下来的n行,而不能获取前面的n行(除非关闭并重新打开光标,如果基础数据正在更改,此时结果集可能不同)

因为游标是只向前的,所以在打开游标的过程和该过程的调用方中从游标中提取是不可能有意义的。从语法上讲,这样做是完全正确的。但这意味着调用者将永远看不到查询返回的第一行,这很可能不是您想要的。如果要从调用者中的游标获取数据,则过程应该只打开游标。如果要从过程中的游标获取数据,则不应将其返回给调用方


另外,几乎可以肯定的是,任何过程都没有“返回状态”参数。如果过程遇到无法解决的错误,则应引发异常。调用方不应该依赖于检查返回状态,它应该捕获它可以处理的特定异常,并让其余异常传播到调用堆栈中。一个
,当其他的
异常处理程序(比如您这里的异常处理程序)没有执行
引发
时,几乎可以肯定是错误,其唯一影响是隐藏错误并删除有关错误发生位置的非常有用的信息。

您的同事是正确的。包过程不需要FETCH语句。它不需要局部变量。它不需要WHEN-OTHERS异常处理程序

如果要返回一个ref游标,该过程应该只打开游标。 例如,这就足够了:

PROCEDURE emp_pay_period_proc(p_user_id IN VARCHAR2, p_pay_period OUT SYS_REFCURSOR)
IS
BEGIN
   OPEN p_pay_period FOR

      SELECT ptp.start_date AS pay_period_start_date
           , ptp.end_date   AS pay_period_end_date
        FROM pay_period ptp
       WHERE ptp.tso_td = p_user_id
       GROUP BY ptp.start_date, ptp.end_date;

END;
如果我需要返回一个ref游标,我个人的偏好是使用函数而不是过程。但考虑到问题中提供的示例,我认为ref游标并不是最合适的设计

PROCEDURE emp_pay_period_proc(p_user_id IN VARCHAR2, p_pay_period OUT SYS_REFCURSOR)
IS
BEGIN
   OPEN p_pay_period FOR

      SELECT ptp.start_date AS pay_period_start_date
           , ptp.end_date   AS pay_period_end_date
        FROM pay_period ptp
       WHERE ptp.tso_td = p_user_id
       GROUP BY ptp.start_date, ptp.end_date;

END;