PKG_COLLECTION_LHR 存储过程或函数返回集合类型

存储过程或函数可以返回集合类型,方法很多,今天整理在一个包中,其它情况可照猫画虎。

 

CREATE OR REPLACE PACKAGE PKG_COLLECTION_LHR AUTHID CURRENT_USER AS

  -----------------------------------------------------------------------------------
  -- Created on 2013-05-24 14:37:41 by lhr
  --Changed on 2013-05-24 14:37:41 by lhr
  -- function:  返回各种各样的集合   
	/*
	DROP TYPE obj_all_address_lhr FORCE;
DROP TYPE typ_all_address_lhr FORCE;
 
CREATE OR REPLACE TYPE obj_all_address_lhr AS OBJECT(
    P_LEVEL        NUMBER(18),
    EMPNO          NUMBER(18),
    ENAME          VARCHAR2(4000),
    MGR            NUMBER(18),
    NAME_ALL     VARCHAR2(4000),
    ALL_NAME_LEVEL VARCHAR2(4000),
    ROOT           VARCHAR2(4000),
    IS_LEAF        VARCHAR2(10)
    );
CREATE OR REPLACE TYPE typ_all_address_lhr AS TABLE OF obj_all_address_lhr;
*/
  -----------------------------------------------------------------------------------

  -----------------------------变量--------------------------------------
  TYPE TYPE_CURSOR IS REF CURSOR;
  TYPE TYPE_RECORD IS RECORD(
    P_LEVEL        NUMBER(18),
    EMPNO          NUMBER(18),
    ENAME          VARCHAR2(4000),
    MGR            NUMBER(18),
    NAME_ALL     VARCHAR2(4000),
    ALL_NAME_LEVEL VARCHAR2(4000),
    ROOT           VARCHAR2(4000),
    IS_LEAF        VARCHAR2(10));
  TYPE T_RECORD IS TABLE OF TYPE_RECORD;

  -----------------------------存过--------------------------------------
  --系统游标  --推荐
  PROCEDURE P_SYS_REFCURSOR_LHR(P_EMPNO IN NUMBER,
                                CUR_SYS     OUT SYS_REFCURSOR);
  -- 自定义游标
  PROCEDURE P_SYS_REFCURSOR_LHR_01(P_EMPNO IN NUMBER,
                                   CUR_SYS     OUT TYPE_CURSOR);

  ---索引表  --包级别
  PROCEDURE P_INDEX_TABLE_PKG_LHR(P_EMPNO IN NUMBER,
                                  O_T_RECORD  OUT T_RECORD);

  ------------------------------函数-------------------------------------
  --系统游标
  FUNCTION F_GET_SYS_REFCURSOR_LHR(P_EMPNO NUMBER) RETURN SYS_REFCURSOR;

  --索引表   --包 级别   不能通过sql语句直接查询
  FUNCTION F_GET_INDEX_TABLE_PKG_LHR(P_EMPNO NUMBER) RETURN T_RECORD;

  --索引表   --schema 级别  可以直接查询
  /*select D.*   from table( f_get_all_address_lhr(306628323)) D;
  select * from the(select  f_get_all_address_lhr(306628323) from dual);*/
  FUNCTION F_GET_INDEX_TABLE_SCHEMA_LHR(P_EMPNO NUMBER)
    RETURN TYP_ALL_ADDRESS_LHR;

  ---- 索引表   --schema 级别 --管道化 可以直接查询
  FUNCTION F_GET_INDEX_TABLE_PIPE_LHR(P_EMPNO NUMBER)
    RETURN TYP_ALL_ADDRESS_LHR
    PIPELINED;

END PKG_COLLECTION_LHR;
/
CREATE OR REPLACE PACKAGE BODY PKG_COLLECTION_LHR AS

  PROCEDURE P_SYS_REFCURSOR_LHR(P_EMPNO IN NUMBER,
                                CUR_SYS     OUT SYS_REFCURSOR) IS
  
    /*DECLARE
  CUR_A         SYS_REFCURSOR;
  R_TYPE_RECORD PKG_COLLECTION_LHR.TYPE_RECORD;
BEGIN
  PKG_COLLECTION_LHR.P_SYS_REFCURSOR_LHR(7900, CUR_A);
  LOOP
    FETCH CUR_A
      INTO R_TYPE_RECORD;
    EXIT WHEN CUR_A%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(R_TYPE_RECORD.EMPNO);
  END LOOP;
END;
*/
  BEGIN
    OPEN CUR_SYS FOR
      SELECT LEVEL P_LEVEL,
             T.EMPNO,
             T.ENAME,
             T.MGR,
             (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || T.ENAME || '(' ||
             T.EMPNO || ')') NAME_ALL,
             SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
             CONNECT_BY_ROOT(T.ENAME) ROOT,
             DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
        FROM SCOTT.EMP T
       START WITH MGR IS NULL
      CONNECT BY NOCYCLE MGR = PRIOR EMPNO;
  
  EXCEPTION
    WHEN OTHERS THEN
      NULL;
  END P_SYS_REFCURSOR_LHR;

  ------------------------------------------------------------------------------------------------------
  PROCEDURE P_SYS_REFCURSOR_LHR_01(P_EMPNO IN NUMBER,
                                   CUR_SYS     OUT TYPE_CURSOR) IS
  
    /*  --测试:
  DECLARE
  CUR_A         PKG_COLLECTION_LHR.TYPE_CURSOR;
  R_TYPE_RECORD PKG_COLLECTION_LHR.TYPE_RECORD;
BEGIN
  PKG_COLLECTION_LHR.P_SYS_REFCURSOR_LHR_01(7809, CUR_A);
  LOOP
    FETCH CUR_A
      INTO R_TYPE_RECORD;
    EXIT WHEN CUR_A%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(R_TYPE_RECORD.EMPNO);
  END LOOP;
END;
*/
  BEGIN
    OPEN CUR_SYS FOR
      SELECT LEVEL P_LEVEL,
             T.EMPNO,
             T.ENAME,
             T.MGR,
             (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || T.ENAME || '(' ||
             T.EMPNO || ')') NAME_ALL,
             SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
             CONNECT_BY_ROOT(T.ENAME) ROOT,
             DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
        FROM SCOTT.EMP T
       START WITH MGR IS NULL
      CONNECT BY NOCYCLE MGR = PRIOR EMPNO;
  
  EXCEPTION
    WHEN OTHERS THEN
      NULL;
  END P_SYS_REFCURSOR_LHR_01;

  ------------------------------------------------------------------------------------------------------

  PROCEDURE P_INDEX_TABLE_PKG_LHR(P_EMPNO IN NUMBER,
                                  O_T_RECORD  OUT T_RECORD) IS
           /*  --测试:
  DECLARE
  CUR_A         PKG_COLLECTION_LHR.TYPE_CURSOR;
  R_TYPE_RECORD PKG_COLLECTION_LHR.TYPE_RECORD;
BEGIN
  PKG_COLLECTION_LHR.P_SYS_REFCURSOR_LHR_01(306628323, CUR_A);
  LOOP
    FETCH CUR_A
      INTO R_TYPE_RECORD;
    EXIT WHEN CUR_A%NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(R_TYPE_RECORD.EMPNO);
  END LOOP;
END;
*/

    R_TYPE TYPE_RECORD;
  
  BEGIN
    O_T_RECORD := T_RECORD(); -- 注意这句不能丢  不然会报:ORA-06531: 引用未初始化的收集
    FOR CUR IN (SELECT LEVEL P_LEVEL,
                       T.EMPNO,
                       T.ENAME,
                       T.MGR,
                       (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' ||
                       T.ENAME || '(' || T.EMPNO || ')') NAME_ALL,
                       SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
                       CONNECT_BY_ROOT(T.ENAME) ROOT,
                       DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
                  FROM SCOTT.EMP T
                 START WITH MGR IS NULL
                CONNECT BY NOCYCLE MGR = PRIOR EMPNO) LOOP 
      R_TYPE.P_LEVEL        := CUR.P_LEVEL;
      R_TYPE.ALL_NAME_LEVEL := CUR.ALL_NAME_LEVEL;
      R_TYPE.ROOT           := CUR.ROOT;
      R_TYPE.IS_LEAF        := CUR.IS_LEAF;
      O_T_RECORD.EXTEND;
      O_T_RECORD(O_T_RECORD.LAST) := R_TYPE;
    END LOOP;
  
  EXCEPTION
    WHEN OTHERS THEN
      NULL;
  END P_INDEX_TABLE_PKG_LHR;
  ------------------------------------------------------------------------------------------------------

  ------------------------------------------------------------------------------------------------------

  FUNCTION F_GET_SYS_REFCURSOR_LHR(P_EMPNO NUMBER) RETURN SYS_REFCURSOR IS
  
    -----------------------------------------------------------------------------------
    -- Created on 2013-05-24 14:37:41 by lhr
    --Changed on 2013-05-24 14:37:41 by lhr
    -- function:
    --测试: SELECT pkg_collection_lhr.f_get_SYS_REFCURSOR_lhr(306628323)  FROM   dual;
    -----------------------------------------------------------------------------------
  
    CUR_SYS SYS_REFCURSOR;
  BEGIN
    OPEN CUR_SYS FOR
      SELECT LEVEL P_LEVEL,
             T.EMPNO,
             T.ENAME,
             T.MGR,
             (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || T.ENAME || '(' ||
             T.EMPNO || ')') NAME_ALL,
             SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
             CONNECT_BY_ROOT(T.ENAME) ROOT,
             DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
        FROM SCOTT.EMP T
       START WITH MGR IS NULL
      CONNECT BY NOCYCLE MGR = PRIOR EMPNO;
  
    RETURN CUR_SYS;
  EXCEPTION
    WHEN OTHERS THEN
      NULL;
  END;

  ------------------------------------------------------------------------------------------------------

  FUNCTION F_GET_INDEX_TABLE_PKG_LHR(P_EMPNO NUMBER) RETURN T_RECORD IS
    O_T_RECORD T_RECORD;
    R_TYPE     TYPE_RECORD;
  
    /*DECLARE
    RESULT pkg_collection_lhr.t_record;
    BEGIN
    -- Call the function
    RESULT := pkg_collection_lhr.f_get_index_table_pkg_lhr(P_EMPNO => 306628323);
    
    dbms_output.put_line(RESULT(1).id);
    END;*/
  
  BEGIN
    O_T_RECORD := T_RECORD(); -- 注意这句不能丢  不然会报:ORA-06531: 引用未初始化的收集
    FOR CUR IN (SELECT LEVEL P_LEVEL,
                       T.EMPNO,
                       T.ENAME,
                       T.MGR,
                       (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' ||
                       T.ENAME || '(' || T.EMPNO || ')') NAME_ALL,
                       SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
                       CONNECT_BY_ROOT(T.ENAME) ROOT,
                       DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
                  FROM SCOTT.EMP T
                 START WITH MGR IS NULL
                CONNECT BY NOCYCLE MGR = PRIOR EMPNO) LOOP
    
      R_TYPE.P_LEVEL        := CUR.P_LEVEL;
      R_TYPE.ALL_NAME_LEVEL := CUR.ALL_NAME_LEVEL;
      R_TYPE.ROOT           := CUR.ROOT;
      R_TYPE.IS_LEAF        := CUR.IS_LEAF;
      O_T_RECORD.EXTEND;
      O_T_RECORD(O_T_RECORD.LAST) := R_TYPE;
    
      RETURN O_T_RECORD;
    END LOOP;
  END F_GET_INDEX_TABLE_PKG_LHR;

  -----------------------------------------------------------------------------------
  -- Created on 2012/8/20 11:33:07 by lhr
  --Changed on 2012/8/20 11:33:07 by lhr
  -- function:

  /*select D.*   from table( f_get_all_address_lhr(306628323)) D;
  select * from the(select  f_get_all_address_lhr(306628323) from dual);*/
  -----------------------------------------------------------------------------------
  FUNCTION F_GET_INDEX_TABLE_SCHEMA_LHR(P_EMPNO NUMBER)
    RETURN TYP_ALL_ADDRESS_LHR IS
  
    SP_TABLE_LHR TYP_ALL_ADDRESS_LHR := TYP_ALL_ADDRESS_LHR();
  
    -- sp_table_lhr typ_all_address_lhr ;
  BEGIN
  
    SELECT OBJ_ALL_ADDRESS_LHR(P_LEVEL,
                               EMPNO,
                               ENAME,
                               MGR,
                               NAME_ALL,
                               ALL_NAME_LEVEL,
                               ROOT,
                               IS_LEAF)
      BULK COLLECT
      INTO SP_TABLE_LHR
      FROM (SELECT LEVEL P_LEVEL,
                   T.EMPNO,
                   T.ENAME,
                   T.MGR,
                   (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || T.ENAME || '(' ||
                   T.EMPNO || ')') NAME_ALL,
                   SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
                   CONNECT_BY_ROOT(T.ENAME) ROOT,
                   DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
              FROM SCOTT.EMP T
             START WITH MGR IS NULL
            CONNECT BY NOCYCLE MGR = PRIOR EMPNO);
  
    ---或者用如下的for循环
    /*    FOR cur IN (SELECT LEVEL p_level,
    t.id,
    t.parentid,
    t.assemblename,
    t.addresslevel,
    (SELECT d.description
    FROM   x_dictionary d
    WHERE  d. classid = 'ADDRESS'
    AND    d.attributeid = 'ADDRESSLEVEL'
    AND    d.value = t.addresslevel) add_level_description,
    (lpad(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || t.name || '(' || t.id || ')') NAME_ALL,
    substr(sys_connect_by_path(t.name, '=>'), 3) all_name_level,
    connect_by_root(t.name) root,
    decode(connect_by_isleaf, 1, 'Y', 0, 'N') is_leaf
    FROM   xb_address t
    START  WITH t.id = P_EMPNO
    CONNECT BY nocycle PRIOR t.parentid = id) LOOP
    
    sp_table_lhr.EXTEND;
    sp_table_lhr(sp_table_lhr.last) := obj_all_address_lhr('',
    '',
    '',
    '',
    '',
    '',
    '',
    '',
    '',
    '');
    sp_table_lhr(sp_table_lhr.last).p_level := cur.p_level;
    sp_table_lhr(sp_table_lhr.last).id := cur.id;
    sp_table_lhr(sp_table_lhr.last).parentid := cur.parentid;
    END LOOP;
    */
  
    ---或者用如下的for循环
    /*              FOR cur IN (SELECT LEVEL p_level,
    t.id,
    t.parentid,
    t.assemblename,
    t.addresslevel,
    (SELECT d.description
    FROM   x_dictionary d
    WHERE  d. classid = 'ADDRESS'
    AND    d.attributeid = 'ADDRESSLEVEL'
    AND    d.value = t.addresslevel) add_level_description,
    (lpad(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || t.name || '(' || t.id || ')') NAME_ALL,
    substr(sys_connect_by_path(t.name, '=>'), 3) all_name_level,
    connect_by_root(t.name) root,
    decode(connect_by_isleaf, 1, 'Y', 0, 'N') is_leaf
    FROM   xb_address t
    START  WITH t.id = P_EMPNO
    CONNECT BY nocycle PRIOR t.parentid = id) LOOP
    
    sp_table_lhr.EXTEND;
    sp_table_lhr(sp_table_lhr.last) := obj_all_address_lhr(cur.p_level,
    cur.id,
    cur.parentid,
    cur.assemblename,
    cur.addresslevel,
    cur.add_level_description,
    cur.NAME_ALL,
    cur.all_name_level,
    cur.root,
    cur.is_leaf);
    END LOOP;
    */
    RETURN SP_TABLE_LHR;
  END F_GET_INDEX_TABLE_SCHEMA_LHR;

  ------------------------------------------------------------------------------------------------------
  FUNCTION F_GET_INDEX_TABLE_PIPE_LHR(P_EMPNO NUMBER)
    RETURN TYP_ALL_ADDRESS_LHR
    PIPELINED IS
  
    SP_TABLE_LHR OBJ_ALL_ADDRESS_LHR;
  BEGIN
  
    FOR CUR IN (SELECT LEVEL P_LEVEL,
                       T.EMPNO,
                       T.ENAME,
                       T.MGR,
                       (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' ||
                       T.ENAME || '(' || T.EMPNO || ')') NAME_ALL,
                       SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
                       CONNECT_BY_ROOT(T.ENAME) ROOT,
                       DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
                  FROM SCOTT.EMP T
                 START WITH MGR IS NULL
                CONNECT BY NOCYCLE MGR = PRIOR EMPNO) LOOP
    
      SP_TABLE_LHR := OBJ_ALL_ADDRESS_LHR(CUR.P_LEVEL,
                                          CUR.Empno,
                                          CUR.Ename,
                                          CUR.Mgr,
                                          cur.NAME_ALL,
                                          CUR.ALL_NAME_LEVEL,
                                          CUR.ROOT,
                                          CUR.IS_LEAF);
      PIPE ROW(SP_TABLE_LHR);
    
    END LOOP;
  
    RETURN;
  END F_GET_INDEX_TABLE_PIPE_LHR;

END PKG_COLLECTION_LHR;
/

 

 

About Me

...............................................................................................................................

● 本文作者:小麦苗,只专注于数据库的技术,更注重技术的运用

● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新

● 本文itpub地址:http://blog.itpub.net/26736162/viewspace-2131977/

● 本文博客园地址:http://www.cnblogs.com/lhrbest/p/6254053.html

● 本文pdf版及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/

● QQ群:230161599     微信群:私聊

● 联系我请加QQ好友(642808185),注明添加缘由

● 于 2016-12-26 08:00 ~ 2016-12-27 24:00 在农行完成

● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解

● 版权所有,欢迎分享本文,转载请保留出处

...............................................................................................................................

手机长按下图识别二维码或微信客户端扫描下边的二维码来关注小麦苗的微信公众号:xiaomaimiaolhr,免费学习最实用的数据库技术。

 

 

 

posted @ 2017-01-05 21:07  DB宝  阅读(682)  评论(0编辑  收藏  举报