• 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,免费学习最实用的数据库技术。

     

     

  • 相关阅读:
    关于字典中可迭代的一个问题
    关于python字典还不错的一个总结
    代码17
    python文件读写,以后就用with open语句
    myeclipse配置内存
    android官网被封掉了,仅仅好用这个站点进谷歌了!嘎嘎
    IE input X 去掉文本框的叉叉和password输入框的眼睛图标
    【Bootstrap】一个PC、平板、手机同一时候使用并且美观的登陆页面
    110个经常使用Oracle函数总结
    索引
  • 原文地址:https://www.cnblogs.com/lhrbest/p/6254053.html
Copyright © 2020-2023  润新知