如何使用 out sys_refcursor 参数执行 oracle 过程?

Posted

技术标签:

【中文标题】如何使用 out sys_refcursor 参数执行 oracle 过程?【英文标题】:How to execute an oracle procedure with an out sys_refcursor parameter? 【发布时间】:2014-06-04 04:18:10 【问题描述】:

我的包体中有一个 proc:

create or replace package body MYPACKAGE is

    procedure "GetAllRules"(p_rules     out sys_refcursor)
    is
    begin
        open p_rules for
        select * from my_rules;

    end "GetAllRules";

-- etc

我将在我的包装规范中公开这一点。

如何在 PL SQL Developer(或类似软件)的新 SQL 窗口中执行此过程?

【问题讨论】:

【参考方案1】:

您可以相对轻松地执行该过程

DECLARE 
  l_rc sys_refcursor;
BEGIN
  mypackage."GetAllRules"( l_rc );
END;

当然,这只是将光标返回给调用应用程序。它不做任何事情来从游标中获取数据,对这些数据做一些事情,或者关闭游标。假设您的目标是将一些数据写入dbms_output(这有时对原型设计很有用,但不是生产代码应该依赖的东西),您可以执行类似的操作

DECLARE 
  l_rc sys_refcursor;
  l_rec my_rules%rowtype;
BEGIN
  mypackage."GetAllRules"( l_rc );
  LOOP
     FETCH l_rc INTO l_rec;
     EXIT WHEN l_rc%NOTFOUND;

     dbms_output.put_line( <<print data from l_rec>> );
   END LOOP;

   CLOSE l_rc;
END;

如果你真的在 PL/SQL 中用游标做这样的事情,我强烈建议返回一个强类型的引用游标而不是一个弱类型的游标,这样你就可以声明一条记录游标的%rowtype 而不是强迫调用者确切地知道要声明什么类型并希望过程中的查询不会改变。这也需要您显式编写代码来显示令人讨厌的数据。

如果您使用的是 SQL*Plus(或支持某些 SQL*Plus 命令的工具),您可以稍微简化一下

VARIABLE rc REFCURSOR;
EXEC mypackage."GetAllRules"( :rc );
PRINT :rc;

顺便说一句,我不喜欢使用区分大小写的标识符。每次调用时都必须用双引号将 "GetAllRules" 之类的标识符括起来。除非您有真正令人信服的理由,否则我建议您使用标准的不区分大小写的标识符。在您的代码中合理地大写标识符是完全合理的,当然,努力强制它们在数据字典中区分大小写是没有多大意义的。

【讨论】:

谢谢你 - 这回答了我所有的问题等等。感谢提示 RE:区分大小写的标识符。我是 Oracle 的新手,PL SQL Dev 已经为我生成了它。我会调整的。

以上是关于如何使用 out sys_refcursor 参数执行 oracle 过程?的主要内容,如果未能解决你的问题,请参考以下文章

SYS_REFCURSOR out 参数 - 运行存储过程失败

创建具有 SYS_REFCURSOR 作为输出参数的 mysql 过程时出错

如何将行附加到现有的 SYS_REFCURSOR?

使用 SYS_REFCURSOR OUT 调用过程

无法在实体框架中映射 SYS_REFCURSOR

使用 FOR UPDATE SKIP LOCKED 打开 OUT SYS_REFCURSOR 时出错