簡體   English   中英

Oracle PL / SQL:函數游標

[英]Oracle PL/SQL: Function Cursor

我得到錯誤:

PLS-00231:函數'GET_NUM'不能在SQL中使用

當執行以下代碼時;

CREATE OR REPLACE PACKAGE BODY TESTJNSABC IS

  -- FUNCTION IMPLEMENTATIONS
  FUNCTION get_num(num IN NUMBER) 
    RETURN SYS_REFCURSOR AS
    my_cursor SYS_REFCURSOR;
  BEGIN
    --
    OPEN my_cursor FOR 
    WITH ntable AS (
         SELECT 1 ID, 111 AGT, 'ABC' DESCRIP FROM DUAL
         UNION ALL
         SELECT 2 ID, 222 AGT, 'ABC' DESCRIP FROM DUAL
         UNION ALL
         SELECT 1 ID, 333 AGT, 'ABC' DESCRIP FROM DUAL
    )
    SELECT AGT FROM ntable WHERE ID = num;
    RETURN my_cursor;

  END;

  -- PROCEDURE IMPLEMENTATIONS 
  PROCEDURE testingabc AS

    BEGIN
      WITH xtable AS (
         SELECT 111 AGT, 'A' DESCRIP FROM DUAL
         UNION ALL
         SELECT 222 AGT, 'B' DESCRIP FROM DUAL
         UNION ALL
         SELECT 333 AGT, 'C' DESCRIP FROM DUAL
     )
      SELECT DESCRIP FROM xtable WHERE COD_AGT IN get_num(1);


    END testingabc;

END TESTJNSABC;

即使我將函數稱為TESTJNSABC.get_num(1)我仍然會遇到相同的錯誤。 -更新。 因此,在現實生活中,我想從WHERE子句中調用Function; 該函數應返回一組NUMBER值(這就是我使用IN子句的原因)。

那么,是否有可能在“過程”上創建變量並將Function值分配給該變量? 比方說

根本不是問題,這是否是正確的方法。 當然,您可以按照自己的方式進行操作,但是正如專家建議的那樣,這不是正確而有效的方法。 看看如何做到。 PS:未經測試。

CREATE OR REPLACE PACKAGE BODY TESTJNSABC IS

  -- FUNCTION IMPLEMENTATIONS
  FUNCTION get_num(num IN NUMBER) 
    RETURN SYS_REFCURSOR AS
    my_cursor SYS_REFCURSOR;
  BEGIN
    --
    OPEN my_cursor FOR 
    WITH ntable AS (
         SELECT 1 ID, 111 AGT, 'ABC' DESCRIP FROM DUAL
         UNION ALL
         SELECT 2 ID, 222 AGT, 'ABC' DESCRIP FROM DUAL
         UNION ALL
         SELECT 1 ID, 333 AGT, 'ABC' DESCRIP FROM DUAL
    )
    SELECT AGT FROM ntable WHERE ID = num;
    RETURN my_cursor;

  END;

  -- PROCEDURE IMPLEMENTATIONS 
  PROCEDURE testingabc AS
    --Creating a collection to hold return of the function
    type y is table of varchar2(1000) index by pls_integer; 
    var_z  y; 
    var_1 varchar2(100);

    BEGIN

     Select get_num(1)
     bulk collect into  var_z
     from dual;

    For i in 1..var_z.count
    loop

     WITH xtable AS (
         SELECT 111 AGT, 'A' DESCRIP FROM DUAL
         UNION ALL
         SELECT 222 AGT, 'B' DESCRIP FROM DUAL
         UNION ALL
         SELECT 333 AGT, 'C' DESCRIP FROM DUAL
     )
      SELECT DESCRIP
      into var_1 
      FROM xtable 
      WHERE AGT = var_z(i) ; ---Check each record

      dbms_output.put_line(var_1);

     end loop;

    END testingabc;

END TESTJNSABC;

in ()需要一個子查詢或一個用逗號分隔的值列表,所以不可以,您不能替換返回集合的函數。

假設該函數在SQL查詢范圍內(它是獨立函數或在包規范中聲明),則可以在table()構造中使用它(這需要一個表函數,即它需要返回一個集合,而不是一個光標):

where somecol in (select column_value from table(get_num(1)) )

(或等效的內部聯接等)

通過livesql.oracle.com/apex/livesql/file/content_EF2M0F1LV9LTP6PEII3BDFKAI.html進行演示

編輯:我剛剛注意到問題中的示例嘗試使用ref游標。 請注意, table()運算符適用於集合,而不適用於引用游標。 因此,該函數必須返回集合類型(嵌套表或varray)。

按照@William Robertson的回答,我嘗試實施該解決方案,但出現問題:

[錯誤] ORA-22905(18:26):PL / SQL:ORA-22905:無法訪問非嵌套表項中的行

 -- FUNCTION IMPLEMENTATIONS
 create or replace  FUNCTION get_num(num IN NUMBER) 
    RETURN SYS_REFCURSOR AS
    my_cursor SYS_REFCURSOR;
  BEGIN
    --
    OPEN my_cursor FOR 
    SELECT AGT 
    FROM ntable 
    WHERE ID = num;

    RETURN my_cursor;

  END;

-程序執行

CREATE OR REPLACE PROCEDURE testingabc
AS
type var is table of xtable.DESCRIP%type;    
v_var var;    
BEGIN
    SELECT DESCRIP
    bulk collect into var
     FROM xtable
    WHERE AGT IN (SELECT COLUMN_VALUE
                    FROM TABLE (get_num (1)));
END testingabc;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM