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

Ev.*_*Ev. 1 sql oracle plsql

我的包裹体中有一个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
Run Code Online (Sandbox Code Playgroud)

我在我的软件包规范中公开了这个.

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

Jus*_*ave 6

您可以相对容易地执行该过程

DECLARE 
  l_rc sys_refcursor;
BEGIN
  mypackage."GetAllRules"( l_rc );
END;
Run Code Online (Sandbox Code Playgroud)

当然,这只是将光标返回给调用应用程序.它不会从光标获取数据,对该数据执行某些操作或关闭光标.假设你的目标是写一些数据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;
Run Code Online (Sandbox Code Playgroud)

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

如果您正在使用SQL*Plus(或支持某些SQL*Plus命令的东西),您可以稍微简化一下

VARIABLE rc REFCURSOR;
EXEC mypackage."GetAllRules"( :rc );
PRINT :rc;
Run Code Online (Sandbox Code Playgroud)

顺便说一句,我不喜欢使用区分大小写的标识符."GetAllRules"每次要调用它时,都必须使用双引号括起标识符.除非你有非常令人信服的理由,否则我建议使用标准的不区分大小写的标识符.在代码中合理地利用标识符是完全合理的,当然,在数据字典中强制它们区分大小写并不是很有意义.