【问题标题】:How to call a Stored Procedure to Open Ref Cursors with Different Queries如何调用存储过程以打开具有不同查询的 Ref 游标
【发布时间】:2019-09-29 20:46:13
【问题描述】:

我有一个家庭作业,希望我使用带有游标的存储过程来返回来自多个表的查询。查询会根据一个数字的输入值进行更改,并且查询可以来自单个表或多个表上的联接,具体取决于运行 anon 块的用户选择的数字。我在网上的 oracle 文档中找到了我需要的完美示例,但是文档中没有匿名块来解释如何调用此过程。

已经搜索过堆栈溢出、谷歌和我的 Joan Casteel 的 plsql 书,但我发现大多数匿名块仅从一张表返回查询。只要它不查询多个表,我就可以使用类似的过程运行一个匿名块,并且我的匿名块仅在它返回单个变量而不是多列表时运行。

这是来自 oracle 文档的代码:

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; /

我会发布我的家庭作业,但我认为我最好理解一个示例并尝试应用它。你会如何写匿名块?

【问题讨论】:

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


    【解决方案1】:

    我不确定你为什么如此关注匿名区块;尽管可以这样做,但您的任务说要使用存储过程(我认为它也可以是一个函数);此外,过程更有意义。

    无论如何,这里有一个 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>
    

    【讨论】:

    • 作业目标是使用 PL/SQL 匿名块调用存储过程,并部分根据是否符合作业要求进行评分。教授不是将存储过程复制到命令行或使用SELECT语句调用它,而是执行匿名块
    猜你喜欢
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 2011-01-24
    • 1970-01-01
    • 2021-12-02
    • 2010-10-26
    • 2017-03-15
    • 2010-10-06
    相关资源
    最近更新 更多