PKG_COLLECTION_LHR 儲存過程或函式返回集合型別

lhrbest發表於2017-01-05

儲存過程或函式可以返回集合型別,方法很多,今天整理在一個包中,其它情況可照貓畫虎。

點選(此處)摺疊或開啟

  1. CREATE OR REPLACE PACKAGE PKG_COLLECTION_LHR AUTHID CURRENT_USER AS

  2.   -----------------------------------------------------------------------------------
  3.   -- Created on 2013-05-24 14:37:41 by lhr
  4.   --Changed on 2013-05-24 14:37:41 by lhr
  5.   -- function: 返回各種各樣的集合
  6.     /*
  7.     DROP TYPE obj_all_address_lhr FORCE;
  8. DROP TYPE typ_all_address_lhr FORCE;
  9.  
  10. CREATE OR REPLACE TYPE obj_all_address_lhr AS OBJECT(
  11.     P_LEVEL NUMBER(18),
  12.     EMPNO NUMBER(18),
  13.     ENAME VARCHAR2(4000),
  14.     MGR NUMBER(18),
  15.     NAME_ALL VARCHAR2(4000),
  16.     ALL_NAME_LEVEL VARCHAR2(4000),
  17.     ROOT VARCHAR2(4000),
  18.     IS_LEAF VARCHAR2(10)
  19.     );
  20. CREATE OR REPLACE TYPE typ_all_address_lhr AS TABLE OF obj_all_address_lhr;
  21. */
  22.   -----------------------------------------------------------------------------------

  23.   -----------------------------變數--------------------------------------
  24.   TYPE TYPE_CURSOR IS REF CURSOR;
  25.   TYPE TYPE_RECORD IS RECORD(
  26.     P_LEVEL NUMBER(18),
  27.     EMPNO NUMBER(18),
  28.     ENAME VARCHAR2(4000),
  29.     MGR NUMBER(18),
  30.     NAME_ALL VARCHAR2(4000),
  31.     ALL_NAME_LEVEL VARCHAR2(4000),
  32.     ROOT VARCHAR2(4000),
  33.     IS_LEAF VARCHAR2(10));
  34.   TYPE T_RECORD IS TABLE OF TYPE_RECORD;

  35.   -----------------------------存過--------------------------------------
  36.   --系統遊標 --推薦
  37.   PROCEDURE P_SYS_REFCURSOR_LHR(P_EMPNO IN NUMBER,
  38.                                 CUR_SYS OUT SYS_REFCURSOR);
  39.   -- 自定義遊標
  40.   PROCEDURE P_SYS_REFCURSOR_LHR_01(P_EMPNO IN NUMBER,
  41.                                    CUR_SYS OUT TYPE_CURSOR);

  42.   ---索引表 --包級別
  43.   PROCEDURE P_INDEX_TABLE_PKG_LHR(P_EMPNO IN NUMBER,
  44.                                   O_T_RECORD OUT T_RECORD);

  45.   ------------------------------函式-------------------------------------
  46.   --系統遊標
  47.   FUNCTION F_GET_SYS_REFCURSOR_LHR(P_EMPNO NUMBER) RETURN SYS_REFCURSOR;

  48.   --索引表 --包 級別 不能通過sql語句直接查詢
  49.   FUNCTION F_GET_INDEX_TABLE_PKG_LHR(P_EMPNO NUMBER) RETURN T_RECORD;

  50.   --索引表 --schema 級別 可以直接查詢
  51.   /*select D.* from table( f_get_all_address_lhr(306628323)) D;
  52.   select * from the(select f_get_all_address_lhr(306628323) from dual);*/
  53.   FUNCTION F_GET_INDEX_TABLE_SCHEMA_LHR(P_EMPNO NUMBER)
  54.     RETURN TYP_ALL_ADDRESS_LHR;

  55.   ---- 索引表 --schema 級別 --管道化 可以直接查詢
  56.   FUNCTION F_GET_INDEX_TABLE_PIPE_LHR(P_EMPNO NUMBER)
  57.     RETURN TYP_ALL_ADDRESS_LHR
  58.     PIPELINED;

  59. END PKG_COLLECTION_LHR;
  60. /
  61. CREATE OR REPLACE PACKAGE BODY PKG_COLLECTION_LHR AS

  62.   PROCEDURE P_SYS_REFCURSOR_LHR(P_EMPNO IN NUMBER,
  63.                                 CUR_SYS OUT SYS_REFCURSOR) IS
  64.   
  65.     /*DECLARE
  66.   CUR_A SYS_REFCURSOR;
  67.   R_TYPE_RECORD PKG_COLLECTION_LHR.TYPE_RECORD;
  68. BEGIN
  69.   PKG_COLLECTION_LHR.P_SYS_REFCURSOR_LHR(7900, CUR_A);
  70.   LOOP
  71.     FETCH CUR_A
  72.       INTO R_TYPE_RECORD;
  73.     EXIT WHEN CUR_A%NOTFOUND;
  74.     DBMS_OUTPUT.PUT_LINE(R_TYPE_RECORD.EMPNO);
  75.   END LOOP;
  76. END;
  77. */
  78.   BEGIN
  79.     OPEN CUR_SYS FOR
  80.       SELECT LEVEL P_LEVEL,
  81.              T.EMPNO,
  82.              T.ENAME,
  83.              T.MGR,
  84.              (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || T.ENAME || '(' ||
  85.              T.EMPNO || ')') NAME_ALL,
  86.              SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
  87.              CONNECT_BY_ROOT(T.ENAME) ROOT,
  88.              DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
  89.         FROM SCOTT.EMP T
  90.        START WITH MGR IS NULL
  91.       CONNECT BY NOCYCLE MGR = PRIOR EMPNO;
  92.   
  93.   EXCEPTION
  94.     WHEN OTHERS THEN
  95.       NULL;
  96.   END P_SYS_REFCURSOR_LHR;

  97.   ------------------------------------------------------------------------------------------------------
  98.   PROCEDURE P_SYS_REFCURSOR_LHR_01(P_EMPNO IN NUMBER,
  99.                                    CUR_SYS OUT TYPE_CURSOR) IS
  100.   
  101.     /* --測試:
  102.   DECLARE
  103.   CUR_A PKG_COLLECTION_LHR.TYPE_CURSOR;
  104.   R_TYPE_RECORD PKG_COLLECTION_LHR.TYPE_RECORD;
  105. BEGIN
  106.   PKG_COLLECTION_LHR.P_SYS_REFCURSOR_LHR_01(7809, CUR_A);
  107.   LOOP
  108.     FETCH CUR_A
  109.       INTO R_TYPE_RECORD;
  110.     EXIT WHEN CUR_A%NOTFOUND;
  111.     DBMS_OUTPUT.PUT_LINE(R_TYPE_RECORD.EMPNO);
  112.   END LOOP;
  113. END;
  114. */
  115.   BEGIN
  116.     OPEN CUR_SYS FOR
  117.       SELECT LEVEL P_LEVEL,
  118.              T.EMPNO,
  119.              T.ENAME,
  120.              T.MGR,
  121.              (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || T.ENAME || '(' ||
  122.              T.EMPNO || ')') NAME_ALL,
  123.              SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
  124.              CONNECT_BY_ROOT(T.ENAME) ROOT,
  125.              DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
  126.         FROM SCOTT.EMP T
  127.        START WITH MGR IS NULL
  128.       CONNECT BY NOCYCLE MGR = PRIOR EMPNO;
  129.   
  130.   EXCEPTION
  131.     WHEN OTHERS THEN
  132.       NULL;
  133.   END P_SYS_REFCURSOR_LHR_01;

  134.   ------------------------------------------------------------------------------------------------------

  135.   PROCEDURE P_INDEX_TABLE_PKG_LHR(P_EMPNO IN NUMBER,
  136.                                   O_T_RECORD OUT T_RECORD) IS
  137.            /* --測試:
  138.   DECLARE
  139.   CUR_A PKG_COLLECTION_LHR.TYPE_CURSOR;
  140.   R_TYPE_RECORD PKG_COLLECTION_LHR.TYPE_RECORD;
  141. BEGIN
  142.   PKG_COLLECTION_LHR.P_SYS_REFCURSOR_LHR_01(306628323, CUR_A);
  143.   LOOP
  144.     FETCH CUR_A
  145.       INTO R_TYPE_RECORD;
  146.     EXIT WHEN CUR_A%NOTFOUND;
  147.     DBMS_OUTPUT.PUT_LINE(R_TYPE_RECORD.EMPNO);
  148.   END LOOP;
  149. END;
  150. */

  151.     R_TYPE TYPE_RECORD;
  152.   
  153.   BEGIN
  154.     O_T_RECORD := T_RECORD(); -- 注意這句不能丟 不然會報:ORA-06531: 引用未初始化的收集
  155.     FOR CUR IN (SELECT LEVEL P_LEVEL,
  156.                        T.EMPNO,
  157.                        T.ENAME,
  158.                        T.MGR,
  159.                        (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' ||
  160.                        T.ENAME || '(' || T.EMPNO || ')') NAME_ALL,
  161.                        SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
  162.                        CONNECT_BY_ROOT(T.ENAME) ROOT,
  163.                        DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
  164.                   FROM SCOTT.EMP T
  165.                  START WITH MGR IS NULL
  166.                 CONNECT BY NOCYCLE MGR = PRIOR EMPNO) LOOP
  167.       R_TYPE.P_LEVEL := CUR.P_LEVEL;
  168.       R_TYPE.ALL_NAME_LEVEL := CUR.ALL_NAME_LEVEL;
  169.       R_TYPE.ROOT := CUR.ROOT;
  170.       R_TYPE.IS_LEAF := CUR.IS_LEAF;
  171.       O_T_RECORD.EXTEND;
  172.       O_T_RECORD(O_T_RECORD.LAST) := R_TYPE;
  173.     END LOOP;
  174.   
  175.   EXCEPTION
  176.     WHEN OTHERS THEN
  177.       NULL;
  178.   END P_INDEX_TABLE_PKG_LHR;
  179.   ------------------------------------------------------------------------------------------------------

  180.   ------------------------------------------------------------------------------------------------------

  181.   FUNCTION F_GET_SYS_REFCURSOR_LHR(P_EMPNO NUMBER) RETURN SYS_REFCURSOR IS
  182.   
  183.     -----------------------------------------------------------------------------------
  184.     -- Created on 2013-05-24 14:37:41 by lhr
  185.     --Changed on 2013-05-24 14:37:41 by lhr
  186.     -- function:
  187.     --測試: SELECT pkg_collection_lhr.f_get_SYS_REFCURSOR_lhr(306628323) FROM dual;
  188.     -----------------------------------------------------------------------------------
  189.   
  190.     CUR_SYS SYS_REFCURSOR;
  191.   BEGIN
  192.     OPEN CUR_SYS FOR
  193.       SELECT LEVEL P_LEVEL,
  194.              T.EMPNO,
  195.              T.ENAME,
  196.              T.MGR,
  197.              (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || T.ENAME || '(' ||
  198.              T.EMPNO || ')') NAME_ALL,
  199.              SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
  200.              CONNECT_BY_ROOT(T.ENAME) ROOT,
  201.              DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
  202.         FROM SCOTT.EMP T
  203.        START WITH MGR IS NULL
  204.       CONNECT BY NOCYCLE MGR = PRIOR EMPNO;
  205.   
  206.     RETURN CUR_SYS;
  207.   EXCEPTION
  208.     WHEN OTHERS THEN
  209.       NULL;
  210.   END;

  211.   ------------------------------------------------------------------------------------------------------

  212.   FUNCTION F_GET_INDEX_TABLE_PKG_LHR(P_EMPNO NUMBER) RETURN T_RECORD IS
  213.     O_T_RECORD T_RECORD;
  214.     R_TYPE TYPE_RECORD;
  215.   
  216.     /*DECLARE
  217.     RESULT pkg_collection_lhr.t_record;
  218.     BEGIN
  219.     -- Call the function
  220.     RESULT := pkg_collection_lhr.f_get_index_table_pkg_lhr(P_EMPNO => 306628323);
  221.     
  222.     dbms_output.put_line(RESULT(1).id);
  223.     END;*/
  224.   
  225.   BEGIN
  226.     O_T_RECORD := T_RECORD(); -- 注意這句不能丟 不然會報:ORA-06531: 引用未初始化的收集
  227.     FOR CUR IN (SELECT LEVEL P_LEVEL,
  228.                        T.EMPNO,
  229.                        T.ENAME,
  230.                        T.MGR,
  231.                        (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' ||
  232.                        T.ENAME || '(' || T.EMPNO || ')') NAME_ALL,
  233.                        SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
  234.                        CONNECT_BY_ROOT(T.ENAME) ROOT,
  235.                        DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
  236.                   FROM SCOTT.EMP T
  237.                  START WITH MGR IS NULL
  238.                 CONNECT BY NOCYCLE MGR = PRIOR EMPNO) LOOP
  239.     
  240.       R_TYPE.P_LEVEL := CUR.P_LEVEL;
  241.       R_TYPE.ALL_NAME_LEVEL := CUR.ALL_NAME_LEVEL;
  242.       R_TYPE.ROOT := CUR.ROOT;
  243.       R_TYPE.IS_LEAF := CUR.IS_LEAF;
  244.       O_T_RECORD.EXTEND;
  245.       O_T_RECORD(O_T_RECORD.LAST) := R_TYPE;
  246.     
  247.       RETURN O_T_RECORD;
  248.     END LOOP;
  249.   END F_GET_INDEX_TABLE_PKG_LHR;

  250.   -----------------------------------------------------------------------------------
  251.   -- Created on 2012/8/20 11:33:07 by lhr
  252.   --Changed on 2012/8/20 11:33:07 by lhr
  253.   -- function:

  254.   /*select D.* from table( f_get_all_address_lhr(306628323)) D;
  255.   select * from the(select f_get_all_address_lhr(306628323) from dual);*/
  256.   -----------------------------------------------------------------------------------
  257.   FUNCTION F_GET_INDEX_TABLE_SCHEMA_LHR(P_EMPNO NUMBER)
  258.     RETURN TYP_ALL_ADDRESS_LHR IS
  259.   
  260.     SP_TABLE_LHR TYP_ALL_ADDRESS_LHR := TYP_ALL_ADDRESS_LHR();
  261.   
  262.     -- sp_table_lhr typ_all_address_lhr ;
  263.   BEGIN
  264.   
  265.     SELECT OBJ_ALL_ADDRESS_LHR(P_LEVEL,
  266.                                EMPNO,
  267.                                ENAME,
  268.                                MGR,
  269.                                NAME_ALL,
  270.                                ALL_NAME_LEVEL,
  271.                                ROOT,
  272.                                IS_LEAF)
  273.       BULK COLLECT
  274.       INTO SP_TABLE_LHR
  275.       FROM (SELECT LEVEL P_LEVEL,
  276.                    T.EMPNO,
  277.                    T.ENAME,
  278.                    T.MGR,
  279.                    (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || T.ENAME || '(' ||
  280.                    T.EMPNO || ')') NAME_ALL,
  281.                    SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
  282.                    CONNECT_BY_ROOT(T.ENAME) ROOT,
  283.                    DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
  284.               FROM SCOTT.EMP T
  285.              START WITH MGR IS NULL
  286.             CONNECT BY NOCYCLE MGR = PRIOR EMPNO);
  287.   
  288.     ---或者用如下的for迴圈
  289.     /* FOR cur IN (SELECT LEVEL p_level,
  290.     t.id,
  291.     t.parentid,
  292.     t.assemblename,
  293.     t.addresslevel,
  294.     (SELECT d.description
  295.     FROM x_dictionary d
  296.     WHERE d. classid = 'ADDRESS'
  297.     AND d.attributeid = 'ADDRESSLEVEL'
  298.     AND d.value = t.addresslevel) add_level_description,
  299.     (lpad(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || t.name || '(' || t.id || ')') NAME_ALL,
  300.     substr(sys_connect_by_path(t.name, '=>'), 3) all_name_level,
  301.     connect_by_root(t.name) root,
  302.     decode(connect_by_isleaf, 1, 'Y', 0, 'N') is_leaf
  303.     FROM xb_address t
  304.     START WITH t.id = P_EMPNO
  305.     CONNECT BY nocycle PRIOR t.parentid = id) LOOP
  306.     
  307.     sp_table_lhr.EXTEND;
  308.     sp_table_lhr(sp_table_lhr.last) := obj_all_address_lhr('',
  309.     '',
  310.     '',
  311.     '',
  312.     '',
  313.     '',
  314.     '',
  315.     '',
  316.     '',
  317.     '');
  318.     sp_table_lhr(sp_table_lhr.last).p_level := cur.p_level;
  319.     sp_table_lhr(sp_table_lhr.last).id := cur.id;
  320.     sp_table_lhr(sp_table_lhr.last).parentid := cur.parentid;
  321.     END LOOP;
  322.     */
  323.   
  324.     ---或者用如下的for迴圈
  325.     /* FOR cur IN (SELECT LEVEL p_level,
  326.     t.id,
  327.     t.parentid,
  328.     t.assemblename,
  329.     t.addresslevel,
  330.     (SELECT d.description
  331.     FROM x_dictionary d
  332.     WHERE d. classid = 'ADDRESS'
  333.     AND d.attributeid = 'ADDRESSLEVEL'
  334.     AND d.value = t.addresslevel) add_level_description,
  335.     (lpad(' ', 6 * (LEVEL - 1)) || LEVEL || ':' || t.name || '(' || t.id || ')') NAME_ALL,
  336.     substr(sys_connect_by_path(t.name, '=>'), 3) all_name_level,
  337.     connect_by_root(t.name) root,
  338.     decode(connect_by_isleaf, 1, 'Y', 0, 'N') is_leaf
  339.     FROM xb_address t
  340.     START WITH t.id = P_EMPNO
  341.     CONNECT BY nocycle PRIOR t.parentid = id) LOOP
  342.     
  343.     sp_table_lhr.EXTEND;
  344.     sp_table_lhr(sp_table_lhr.last) := obj_all_address_lhr(cur.p_level,
  345.     cur.id,
  346.     cur.parentid,
  347.     cur.assemblename,
  348.     cur.addresslevel,
  349.     cur.add_level_description,
  350.     cur.NAME_ALL,
  351.     cur.all_name_level,
  352.     cur.root,
  353.     cur.is_leaf);
  354.     END LOOP;
  355.     */
  356.     RETURN SP_TABLE_LHR;
  357.   END F_GET_INDEX_TABLE_SCHEMA_LHR;

  358.   ------------------------------------------------------------------------------------------------------
  359.   FUNCTION F_GET_INDEX_TABLE_PIPE_LHR(P_EMPNO NUMBER)
  360.     RETURN TYP_ALL_ADDRESS_LHR
  361.     PIPELINED IS
  362.   
  363.     SP_TABLE_LHR OBJ_ALL_ADDRESS_LHR;
  364.   BEGIN
  365.   
  366.     FOR CUR IN (SELECT LEVEL P_LEVEL,
  367.                        T.EMPNO,
  368.                        T.ENAME,
  369.                        T.MGR,
  370.                        (LPAD(' ', 6 * (LEVEL - 1)) || LEVEL || ':' ||
  371.                        T.ENAME || '(' || T.EMPNO || ')') NAME_ALL,
  372.                        SUBSTR(SYS_CONNECT_BY_PATH(T.ENAME, '=>'), 3) ALL_NAME_LEVEL,
  373.                        CONNECT_BY_ROOT(T.ENAME) ROOT,
  374.                        DECODE(CONNECT_BY_ISLEAF, 1, 'Y', 0, 'N') IS_LEAF
  375.                   FROM SCOTT.EMP T
  376.                  START WITH MGR IS NULL
  377.                 CONNECT BY NOCYCLE MGR = PRIOR EMPNO) LOOP
  378.     
  379.       SP_TABLE_LHR := OBJ_ALL_ADDRESS_LHR(CUR.P_LEVEL,
  380.                                           CUR.Empno,
  381.                                           CUR.Ename,
  382.                                           CUR.Mgr,
  383.                                           cur.NAME_ALL,
  384.                                           CUR.ALL_NAME_LEVEL,
  385.                                           CUR.ROOT,
  386.                                           CUR.IS_LEAF);
  387.       PIPE ROW(SP_TABLE_LHR);
  388.     
  389.     END LOOP;
  390.   
  391.     RETURN;
  392.   END F_GET_INDEX_TABLE_PIPE_LHR;

  393. END PKG_COLLECTION_LHR;
  394. /

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),註明新增緣由

● 於 2017-01-05 08:00 ~ 2017-01-05 24:00 在農行完成

● 文章內容來源於小麥苗的學習筆記,部分整理自網路,若有侵權或不當之處還請諒解

● 版權所有,歡迎分享本文,轉載請保留出處

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

手機長按下圖識別二維碼或微信客戶端掃描下邊的二維碼來關注小麥苗的微信公眾號:xiaomaimiaolhr,免費學習最實用的資料庫技術。

wpsF8C8.tmp

 

PKG_COLLECTION_LHR  儲存過程或函式返回集合型別



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2131977/,如需轉載,請註明出處,否則將追究法律責任。

相關文章