【问题标题】:Declaring SYS_REFCURSOR and ROWTYPE in stored procedure在存储过程中声明 SYS_REFCURSOR 和 ROWTYPE
【发布时间】:2014-05-20 14:25:48
【问题描述】:

所以我有一个存储过程ONE

create or replace PROCEDURE ONE
(
   A in number
   B in number
   ...
   ZZ out SYS_REFCURSOR
) IS
  SOME_OTHER_STUFF
BEGIN
   ...
END

这会返回一个带有一些我需要的数据的 sys_refcursor。然后我有一个存储过程TWO

create or replace PROCEDURE TWO
(
   A in number
   B in number
   ...
   ZZ out SYS_REFCURSOR
) IS
     Count_Records Sys_Refcursor;
     l_rec Count_Records%rowtype;
BEGIN
    /* get some data from the ONE stored procedure to use on this procedure*/
    ONE(A,B,...Count_Records)

    Loop
       fetch count_records into l_rec;
       Exit When count_records%Notfound;
       If  l_rec.TT_RAW > MAX_RECORDS  Then
         Raise To_Many_Results;
       End If;
    End Loop;

END

当我尝试声明行类型 l_rec Count_Records%rowtype; 时出现错误

如何声明这个变量?问题是 TT_RAW 这是我想要获取的列是一个 SUM 并且光标没有映射到它包含大量计算的任何表。

谢谢

【问题讨论】:

    标签: sql oracle stored-procedures plsql


    【解决方案1】:

    sys_refcursor 的全部意义在于它是动态定义的。另一方面,rowtype 声明必须是静态的(如果不是,编译器无法判断从中引用的字段是否有效)。这是一个用例的定义,您应该定义自己的强类型引用游标,而不是使用sys_refcursor

    下面是一个非常简单的例子:

    CREATE OR REPLACE PACKAGE BODY rc_example IS
       PROCEDURE two (a IN NUMBER, b IN NUMBER);
    END rc_example;
    /
    
    CREATE OR REPLACE PACKAGE BODY rc_example IS
       TYPE one_record IS RECORD (FIRST_VALUE VARCHAR2 (10));
    
       TYPE one_cursor IS REF CURSOR
          RETURN one_record;
    
       --Could alternately be declared using a table's rowtype:
       --TYPE one_cursor is ref cursor return some_table%rowtype;
    
       PROCEDURE one (a IN NUMBER, b IN NUMBER, zz OUT one_cursor) IS
       BEGIN
          OPEN zz FOR SELECT 'test' FROM DUAL;
       END one;
    
       PROCEDURE two (a IN NUMBER, b IN NUMBER) IS
          count_records SYS_REFCURSOR;
          l_rec count_records%ROWTYPE;
       BEGIN
          one (a, b, count_records);
    
          LOOP
             FETCH count_records INTO l_rec;
    
             DBMS_OUTPUT.put_line (l_rec.FIRST_VALUE);
             EXIT WHEN count_records%NOTFOUND;
          END LOOP;
       END two;
    END rc_example;
    /
    

    【讨论】:

    • 感谢您的精彩解释和详尽的示例。我在另一个对我有用的答案上使用了该方法,所以我没有机会尝试您的方法,但是下次我需要执行这样的程序时会考虑它。最好的问候
    【解决方案2】:

    您可以改为获取变量列表,或创建自己的记录类型:

    ...
    fetch count_records into v_field1, v_field2, v_field3
    ...
    

    【讨论】:

    • 试过你的方法,效果很好。感谢您的帮助
    猜你喜欢
    • 2012-06-26
    • 2010-10-12
    • 2017-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    相关资源
    最近更新 更多