从 Oracle 函数返回记录的标准方法是啥?

Posted

技术标签:

【中文标题】从 Oracle 函数返回记录的标准方法是啥?【英文标题】:What is the standard way to return records from an Oracle function?从 Oracle 函数返回记录的标准方法是什么? 【发布时间】:2013-07-15 08:07:18 【问题描述】:

对于我的问题,我确实避免使用“最好”的词,但它确实是最合适的词。

从函数返回记录的最佳(最有效)方式是什么?

目前我有类似的东西:

  FUNCTION myFunct(param1 VARCHAR2) RETURN SYS_REFCURSOR AS
    myCursor SYS_REFCURSOR;
  BEGIN
    OPEN myCursor FOR
    SELECT *
    FROM myTable
    WHERE field = param1;

    RETURN(myCursor);
  END myFunct;

我可以很好地运行它,但是对于我正在阅读的所有其他内容(TABLE 类型、隐式光标等),我真的很困惑什么是最合适的。

附:从 proc 调用它后如何循环遍历这个光标?

编辑: 我读过我只能遍历游标一次(forums.oracle.com/thread/888365),但实际上我想多次循环内容。这是否意味着我选择使用关联数组?

【问题讨论】:

这取决于用例。您是否将数据返回到客户端应用程序?在您的真实代码中,您是否在做一些需要 PL/SQL 的事情?如果没有,为什么不使用视图?您是否正在编写多阶段 ETL 流程?将REF CURSOR 返回到另一段 PL/SQL 是相当不寻常的。 此链接可能对您有所帮助***.com/questions/4125992/… @JustinCave -“将 REF CURSOR 返回到另一段 PL/SQL 是相当不寻常的”。会吗?引用游标使我们可以使用静态或动态 SQL 对结果集进行编程控制。我们可能希望将该程序控制封装在离散函数中,这并不奇怪,尤其是在逻辑复杂的情况下。另外还有一个正常的用例:我们有几段不同的代码都需要读取结果集。 此链接包含如何读取从另一个 pl/sql proc、ado 记录集和 java 中的过程返回的 ref 游标的示例:oracle-base.com/articles/misc/… @APC - 如果您可以返回一个引用游标,那么您很可能可以创建一个视图并将谓词应用于视图而不是将参数传递给函数。如果您将来需要做一些事情,例如将视图加入另一个表,则视图似乎更灵活。在某些情况下,我们希望使用动态 SQL 或根据各种条件从函数返回不同查询的结果。但在我看来,这些都是例外情况,而不是常见情况。 【参考方案1】:
create or replace 
PACKAGE example_pkg AS

    /*
    ** Record and nested table for "dual" table
    ** It is global, you can use it in other packages
    */
    TYPE g_dual_ntt IS TABLE OF SYS.DUAL%ROWTYPE;
    g_dual  g_dual_ntt;

    /*
    ** procedure is public. You may want to use it in different parts of your code
    */
    FUNCTION myFunct(param1 VARCHAR2) RETURN SYS_REFCURSOR;

    /*
    ** Example to work with a cursor
    */
    PROCEDURE example_prc;

END example_pkg;

create or replace 
PACKAGE BODY example_pkg AS

    FUNCTION myFunct(param1 VARCHAR2) RETURN SYS_REFCURSOR
    AS
        myCursor SYS_REFCURSOR;
    BEGIN
        OPEN myCursor FOR
            SELECT  dummy
            FROM    dual
            WHERE   dummy = param1;

        RETURN(myCursor);
    END myFunct;

    PROCEDURE example_prc
    AS
        myCursor SYS_REFCURSOR;
        l_dual   g_dual_ntt; /* With bulk collect there is no need to initialize the collection */
    BEGIN
        -- Open cursor
        myCursor := myFunct('X');
        -- Fetch from cursor  /  all at onece
        FETCH myCursor BULK COLLECT INTO l_dual;
        -- Close cursor
        CLOSE myCursor;

        DBMS_OUTPUT.PUT_LINE('Print: ');
        FOR indx IN 1..l_dual.COUNT LOOP
            DBMS_OUTPUT.PUT_LINE('element: ' || l_dual(indx).dummy );
        END LOOP;
    END example_prc;

END example_pkg;

EXECUTE example_pkg.example_prc();

/*
Print: 
element: X
*/

请查看此链接:http://www.oracle-base.com/articles/misc/using-ref-cursors-to-return-recordsets.php

您可能会发现它很有用...

【讨论】:

接受为答案(唯一答案)。谢谢你,也谢谢你的链接。 @Kampai 没有一种正确的方法来使用游标 (SYS_REFCURSOR)。您可以从函数中返回它或将其设置为变量。它是由你决定。使用它的主要原因是您可能希望为不同的查询打开它,即:不同的 where 条件。

以上是关于从 Oracle 函数返回记录的标准方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

oracle返回1405 1022是啥意思

Oracle 11g - 如何使用表连接从函数返回记录

python中cx_oracle.sessionpool()函数返回值是啥

当我已经返回一个值时,从函数返回错误的最佳方法是啥?

从函数返回多个值的最佳方法是啥?

从函数返回多个值的最佳方法是啥?