Plsql PL/SQL返回游标

Plsql PL/SQL返回游标,plsql,cursor,Plsql,Cursor,我试图定义PL/SQL函数 CREATE OR REPLACE FUNCTION B2BOWNER.F_SSC_Page_Map_Select( p_page_id IN B2BOWNER.SSC_Page_Map.PAGE_ID_NBR%TYPE, p_page_type IN B2BOWNER.SSC_Page_Map.PAGE_TYPE%TYPE,

我试图定义PL/SQL函数

CREATE OR REPLACE FUNCTION B2BOWNER.F_SSC_Page_Map_Select(
                            p_page_id   IN B2BOWNER.SSC_Page_Map.PAGE_ID_NBR%TYPE, 
                            p_page_type IN B2BOWNER.SSC_Page_Map.PAGE_TYPE%TYPE, 
                            p_page_dcpn IN B2BOWNER.SSC_Page_Map.PAGE_DCPN%TYPE)

RETURN MAP_REC

AS

   CURSOR MAP_CURSOR IS

   SELECT * 

   FROM B2BOWNER.SSC_PAGE_MAP 

   WHERE PAGE_ID_NBR = p_page_id AND PAGE_TYPE = p_page_type;

   MAP_REC MAP_CURSOR%ROWTYPE;

   TABLE_DOES_NOT_EXIST exception;  
   PRAGMA EXCEPTION_INIT(TABLE_DOES_NOT_EXIST, -942); -- ORA-00942

BEGIN

   FOR MAP_REC IN MAP_CURSOR

   LOOP

       System.out.println("ID: " + MAP_REC.PAGE_ID_NBR + " " + "TYPE: " + MAP_REC.PAGE_TYPE + " " + "DCPN: " + MAP_REC.PAGE_DCPN);

   END LOOP;

   RETURN MAP_REC;

   EXCEPTION

       WHEN TABLE_DOES_NOT_EXIST THEN

           RETURN -1;

       WHEN DUP_VAL_ON_INDEX THEN

           RETURN -2;

       WHEN INVALID_NUMBER THEN

           RETURN -3;

       WHEN OTHERS THEN

           RETURN -4;

END F_SSC_Page_Map_Select;

SHOW ERRORS PROCEDURE B2BOWNER.F_SSC_Page_Map_Select;

GRANT EXECUTE ON B2BOWNER.F_SSC_Page_Map_Select TO B2B_USER_DBROLE;
并接收以下错误

Warning: compiled but with compilation errors
No errors.
Grant complete.

[Warning] ORA-24344: success with compilation error
6/12    PLS-00320: the declaration of the type of this expression is incomplete or malformed
PL/SQL: Compilation unit analysis terminated
(1: 0): Warning: compiled but with compilation errors

有几件事。首先,在声明部分声明的MAP_REC与游标FOR循环中使用的MAP_REC不同。当我第一次遇到它时,这确实让我感到惊讶,但这是我们都必须习惯的。要执行您试图执行的操作,您需要使用使用游标的OPEN、FETCH和CLOSE方法,或者将游标FOR循环变量的值复制到“声明”变量

其次,不能从此函数返回MAP_REC,因为MAP_REC是在函数内声明的,因此编译器在处理函数定义时不知道。最好使用特定的表行类型

第三,在代码的后面,您有
RETURN-1
等,它不能作为游标%ROWTYPE变量使用。我建议不要试图返回“magic number”值来指示特定的故障,而应该让异常传播到调用方,调用方可以根据需要处理异常。这就是为什么我们有例外——防止每个子程序都有不同的错误处理方案

最后:这是PL/SQL-这里没有System.out.println.:-)

重写代码的一种可能方法是:

CREATE OR REPLACE FUNCTION B2BOWNER.F_SSC_Page_Map_Select(
                            p_page_id   IN B2BOWNER.SSC_Page_Map.PAGE_ID_NBR%TYPE, 
                            p_page_type IN B2BOWNER.SSC_Page_Map.PAGE_TYPE%TYPE, 
                            p_page_dcpn IN B2BOWNER.SSC_Page_Map.PAGE_DCPN%TYPE)
  RETURN B2BOWNER.SSC_PAGE_MAP%ROWTYPE
AS
  CURSOR MAP_CURSOR IS
    SELECT * 
      FROM B2BOWNER.SSC_PAGE_MAP 
      WHERE PAGE_ID_NBR = p_page_id AND
            PAGE_TYPE = p_page_type;

  MAP_REC       B2BOWNER.SSC_PAGE_MAP%ROWTYPE;
  bCursor_open  BOOLEAN := FALSE;
BEGIN
  OPEN MAP_CURSOR;
  bCursor_open := TRUE;

  LOOP
    FETCH MAP_CURSOR
      INTO MAP_REC;
    EXIT WHEN MAP_CURSOR%NOT_FOUND;

    DBMS_OUTPUT.PUT_LINE('ID: ' || MAP_REC.PAGE_ID_NBR || ' ' || 'TYPE: ' || 
                         MAP_REC.PAGE_TYPE || ' ' || 'DCPN: ' || MAP_REC.PAGE_DCPN);
  END LOOP;

  CLOSE MAP_CURSOR;
  bCursor_open := FALSE;

  RETURN MAP_REC;
EXCEPTION
  WHEN OTHERS THEN
    DBMS_OUTPUT.PUT_LINE('Error in F_SSC_Page_Map_Select: ' || SQLCODE || ' ' ||
                         SQLERRM);

    IF bCursor_open THEN
      CLOSE MAP_CURSOR;
    END IF;

    RAISE;
END F_SSC_Page_Map_Select;
祝你好运

分享和享受。

谢谢你,鲍勃。我还发现该网站在演示将包含结果集的游标返回到Java时非常有价值