• 还原 listagg/wm_concat 后的数据 pack_split_listatt ;


    1.创建表并制作测试数据;

    --创建测试表 ;
    CREATE TABLE split_table (
    NAME  VARCHAR2(100),
    ID VARCHAR2(100)
    
    );
    --准备测试数据 ;
    INSERT INTO  split_table VALUES('aa','11,12,13,14,15');
    INSERT INTO  split_table VALUES('bb','aa,bb,cc,dd,');
    INSERT INTO  split_table VALUES('cc','1a,2c,3d,,4c,55,,');
    COMMIT ;

    --原理 ;
    SELECT * FROM TABLE(splitstr((SELECT ID FROM  split_table WHERE NAME='aa' ),',')) a ;

    2.编写拆分函数 :

    CREATE OR REPLACE PACKAGE PACK_SPLIT_LISTAGG IS
    
      TYPE RECORD_SPLIT_TABLE_TYPE IS RECORD(
        V_NAME VARCHAR2(100),
        V_ID   VARCHAR2(100));
      REC_ST RECORD_SPLIT_TABLE_TYPE;
      TYPE SPLIT_TABLE_TYPE IS TABLE OF RECORD_SPLIT_TABLE_TYPE;
      CURSOR CURSOR_ST IS
        SELECT NAME, ID FROM SPLIT_TABLE;
      FUNCTION FUN_TEST_SPLITLISTAGG RETURN SPLIT_TABLE_TYPE
        PIPELINED;
    
    END PACK_SPLIT_LISTAGG;
    /
    
    CREATE OR REPLACE PACKAGE BODY PACK_SPLIT_LISTAGG IS
    
      FUNCTION FUN_TEST_SPLITLISTAGG RETURN SPLIT_TABLE_TYPE
        PIPELINED AS
        ROW_ST      SPLIT_TABLE%ROWTYPE;
        V_START     NUMBER := 1;
        V_INDEX     NUMBER;
        V_LENGTH    NUMBER;
        P_DELIMITER VARCHAR2(100) := ',';
      BEGIN
        OPEN CURSOR_ST;
        LOOP
          FETCH CURSOR_ST
            INTO ROW_ST;
          EXIT WHEN CURSOR_ST%NOTFOUND;
          V_LENGTH := TO_NUMBER(LENGTH(ROW_ST.ID));
          WHILE (V_START <= V_LENGTH) LOOP
            V_INDEX := INSTR(ROW_ST.ID, P_DELIMITER, V_START);
            IF V_INDEX = 0 THEN
              REC_ST.V_NAME := ROW_ST.NAME;
              REC_ST.V_ID   := SUBSTR(ROW_ST.ID, V_START);
              V_START       := V_LENGTH + 1;
            ELSE
              REC_ST.V_NAME := ROW_ST.NAME;
              REC_ST.V_ID   := SUBSTR(ROW_ST.ID, V_START, V_INDEX - V_START);
              V_START       := V_INDEX + 1;
            END IF;
            PIPE ROW(REC_ST);
          END LOOP;
          V_START := 1;
        END LOOP;
        CLOSE CURSOR_ST;
        RETURN;
      EXCEPTION
        WHEN OTHERS THEN
          DBMS_OUTPUT.PUT_LINE(SQLCODE || SQLERRM);
      END FUN_TEST_SPLITLISTAGG;
    END PACK_SPLIT_LISTAGG;
    /

    3.测试代码及结果:

    --测试代码 ;
    SELECT * FROM TABLE(pack_split_listagg.FUN_TEST_SPLITLISTAGG);

    4.谢谢 !

    /* 总结:  pipelined  pipe row ();  

    1. 一般用于返回一个集合;record ,index_table();  nested_table(); array_table();

     2.返回时一次性返回;  3.如果游标的 返回值是cur%rowtype 作为参数传递时应 应使用*(select * from )

     4.因为RECODE()类型和 cursor%row类型一致 所以同3 ;  5.使用游标(weak 弱类型)没有返回值类型那么默认返回的是cur%rowtype 类型;

    */

    SELECT *   FROM TABLE(FUNC_PDT_TAB(CURSOR(SELECT S.PRODUCTID  , S.PRODUCTCODE, S.PRODUCTNAME   FROM SYS_PRODUCT S   ORDER BY S.PRODUCTID)));

    select * FROM sys_product ; select * FROM emp ;

    select * FROM TABLE(TEST_EMP_CURSOR(CURSOR(SELECT e.empno,e.ename,e.job FROM emp e))) ;

    select * FROM TABLE(TEST_EMP_CURSOR_1(CURSOR(SELECT * FROM emp e))) ; --正确的写法;

    select * FROM TABLE(TEST_EMP_CURSOR_1(CURSOR(SELECT e.empno,e.ename,e.job FROM emp e))) ;--抛错!

    select * FROM TABLE(TEST_EMP_CURSOR_2(CURSOR(SELECT e.empno,e.ename,e.job FROM emp e))) ;

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

    PIPELINED 基础用法 :

    CREATE OR REPLACE PACKAGE REFCUR_PKG IS
      TYPE REFCUR_T IS REF CURSOR RETURN EMP_BAK%ROWTYPE;
      TYPE OUTREC_TYP IS RECORD(
        VAR_EMPNO   NUMBER(6),
        VAR_EMPNAME VARCHAR2(30),
        VAR_MGR     VARCHAR2(30));
      TYPE OUTRECSET IS TABLE OF OUTREC_TYP;
      FUNCTION F_TRANS(P REFCUR_T) RETURN OUTRECSET
        PIPELINED;
    END REFCUR_PKG;
    /
    
    CREATE OR REPLACE PACKAGE BODY REFCUR_PKG IS
      FUNCTION F_TRANS(P REFCUR_T) RETURN OUTRECSET
        PIPELINED IS
        OUT_REC OUTREC_TYP;
        IN_REC  P%ROWTYPE;
      BEGIN
        LOOP
          FETCH P
            INTO IN_REC;
          EXIT WHEN P%NOTFOUND;
          -- first row
          OUT_REC.VAR_EMPNO := IN_REC.EMPNO;
          OUT_REC.VAR_ENAME := IN_REC.ENAME;
          OUT_REC.VAR_MGR   := IN_REC.MGR;
          PIPE ROW(OUT_REC);
          -- second row
          OUT_REC.VAR_NUM   := IN_REC.DEPTNO;
          OUT_REC.VAR_CHAR1 := IN_REC.DEPTNO;
          OUT_REC.VAR_CHAR2 := IN_REC.JOB;
          PIPE ROW(OUT_REC);
        END LOOP;
        CLOSE P;
        RETURN;
      END;
    END REFCUR_PKG;
  • 相关阅读:
    网络连接的基本概念,中继系统(网络)
    qnorm 函数 , with 函数(R)
    关于 paste 函数 (R)
    对数据的探索,数据框中是否有大于某个数的值,返回大于的具体的数值,或者数值的坐标(R)
    查看内存占用情况,查看进程,终止进程(cmd)
    查询校园网外网的ip
    二进制的减法(汇编)(数字电路)
    画出箱线图(R)
    排比句(文章写作)
    react中的TS理解
  • 原文地址:https://www.cnblogs.com/linbo3168/p/6066359.html
Copyright © 2020-2023  润新知