如何调用存储过程以打开具有不同查询的Ref游标

时间:2019-05-12 20:09:12

标签: stored-procedures plsql cursor sys-refcursor ref-cursor

我有一项家庭作业,希望我使用带有游标的存储过程从多个表返回查询。查询根据输入值(一个数字)而变化,查询可以来自单个表,也可以来自多个表的联接,具体取决于运行anon块的用户选择的数量。我在oracle联机文档中找到了我需要的完美示例,但是docs中没有匿名块来说明如何调用此过程。

已经从Joan Casteel的堆栈溢出,google和我的plsql书中进行了搜索,但是我发现大多数匿名块仅从一个表返回查询。只要它不查询多个表,我就可以使用一个类似的程序来运行一个匿名块,而我的anon块仅在返回单个变量而不是一个多列表时才运行。

这是来自oracle doc的代码:

CREATE PACKAGE admin_data AS
   TYPE gencurtyp IS REF CURSOR;
   PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT);
END admin_data;
/
CREATE PACKAGE BODY admin_data AS
  PROCEDURE open_cv (generic_cv IN OUT gencurtyp, choice INT) IS
  BEGIN
  IF choice = 1 THEN
     OPEN generic_cv FOR SELECT * FROM employees;
  ELSIF choice = 2 THEN
     OPEN generic_cv FOR SELECT * FROM departments;
  ELSIF choice = 3 THEN
     OPEN generic_cv FOR SELECT * FROM jobs;
  END IF;
END;

END admin_data;    /

我会张贴作业,但我认为最好能理解一个示例并尝试应用它。您将如何编写匿名块?

1 个答案:

答案 0 :(得分:0)

我不确定为什么您会如此关注匿名块;尽管可以这样做,但是您的作业却说要使用存储过程(我猜想它也可以是一个函数);而且,程序更有意义。

无论如何,这是一个SQL * Plus示例,显示了如何执行此操作:

SQL> set pagesize 100
SQL> set verify off
SQL>
SQL> var choice number;
SQL> var rc refcursor;
SQL>
SQL> begin
  2    if &&choice = 1 then
  3       open :rc for select * from dept;
  4    elsif &&choice = 2 then
  5       open :rc for select * From bonus;
  6    elsif &&choice = 3 then
  7       open :rc for select d.dname, e.ename, e.job
  8                    from dept d join emp e on e.deptno = d.deptno;
  9    end if;
 10  end;
 11  /
Enter value for choice: 2

PL/SQL procedure successfully completed.

SQL> print :rc

ENAME      JOB              SAL       COMM
---------- --------- ---------- ----------
KING       PRESIDENT       1000        100

SQL> undefine choice
SQL> /
Enter value for choice: 3

PL/SQL procedure successfully completed.

SQL> print :rc

DNAME                ENAME      JOB
-------------------- ---------- ---------
ACCOUNTING           CLARK      MANAGER
ACCOUNTING           KING       PRESIDENT
ACCOUNTING           MILLER     CLERK
RESEARCH             JONES      MANAGER
RESEARCH             FORD       ANALYST
RESEARCH             ADAMS      CLERK
RESEARCH             SMITH      CLERK
RESEARCH             SCOTT      ANALYST
SALES                WARD       SALESMAN
SALES                TURNER     SALESMAN
SALES                ALLEN      SALESMAN
SALES                JAMES      CLERK
SALES                BLAKE      MANAGER
SALES                MARTIN     SALESMAN

14 rows selected.

SQL>

使用函数的选项如下:如您所见,它几乎与前面的示例相同。

SQL> create or replace function f_test (par_choice in number)
  2    return sys_refcursor
  3  is
  4    rc sys_refcursor;
  5  begin
  6    if par_choice = 1 then
  7       open rc for select * from dept;
  8    elsif par_choice = 2 then
  9       open rc for select * From bonus;
 10    elsif par_choice = 3 then
 11       open rc for select d.dname, e.ename, e.job
 12                    from dept d join emp e on e.deptno = d.deptno;
 13    end if;
 14
 15    return rc;
 16  end;
 17  /

Function created.

SQL> select f_test(2) from dual;

F_TEST(2)
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

ENAME      JOB              SAL       COMM
---------- --------- ---------- ----------
KING       PRESIDENT       1000        100


SQL> select f_test(1) from dual;

F_TEST(1)
--------------------
CURSOR STATEMENT : 1

CURSOR STATEMENT : 1

    DEPTNO DNAME                LOC
---------- -------------------- --------------------
        10 ACCOUNTING           NEW YORK
        20 RESEARCH             DALLAS
        30 SALES                CHICAGO
        40 OPERATIONS           BOSTON


SQL>