Reading clob line by line with pl\sql

后端 未结 9 936
长情又很酷
长情又很酷 2020-12-02 00:53

In my project i use oracle as primary database and i\'ve faced a problem with parsing clob. So suppose we have a clob with value

   aaaaaa
   cccccc
   bbbbb         


        
9条回答
  •  伪装坚强ぢ
    2020-12-02 01:37

    A pipelined function with some additional options to drive the behavior. Tested/works on Windows, Oracle 11g (I have some suspicions it may fail in *nix environments because of how lines terminate).

    CREATE OR REPLACE FUNCTION ETL_HELPER_PARSE
       (P_CLOB NCLOB, P_LINES_TO_SKIP INT DEFAULT 0, P_PUT_EMPTY_LINES CHAR DEFAULT 'N') RETURN SYS.ODCIVarchar2List PIPELINED
    AS
      c_top_lines_to_skip  CONSTANT NUMBER  NOT NULL := P_LINES_TO_SKIP;
      c_output_empty_lines CONSTANT CHAR(1) NOT NULL := P_PUT_EMPTY_LINES; 
      --
      l_len     INT := DBMS_LOB.GETLENGTH(P_CLOB);
      l_hit     INT := 0;
      l_offset  INT := 1;
      l_amount  INT;  
      l_buffer  VARCHAR2(32767);
      l_cnt     INT := 1;  
    BEGIN  
      WHILE ( l_offset < l_len )
      LOOP
        l_hit := DBMS_LOB.INSTR (
         lob_loc    => P_CLOB           -- IN   CLOB      CHARACTER SET ANY_CS
        ,pattern    => CHR(13)||CHR(10) -- IN   VARCHAR2  CHARACTER SET lob_loc%CHARSET
        ,offset     => l_offset         -- IN   INTEGER := 1
        ,nth        => 1                -- IN   INTEGER := 1
        );
        l_amount := CASE WHEN COALESCE(l_hit, 0) > 0 THEN l_hit - l_offset ELSE l_len - l_offset + 1 END;
        -- `l_amount=0` means a new empty line has been encountered
        IF l_cnt > c_top_lines_to_skip       
        THEN
          IF l_amount > 0
          THEN
            DBMS_LOB.READ(P_CLOB, l_amount, l_offset, l_buffer);
            PIPE ROW (l_buffer);
          ELSIF UPPER(c_output_empty_lines) = 'Y'
          THEN
            PIPE ROW ('');
          END IF;
        END IF;
    
        l_offset := CASE WHEN COALESCE(l_hit, 0) > 0  THEN l_hit + 2 ELSE l_len END;    
        l_cnt := l_cnt + 1;
      end loop;
    EXCEPTION
      WHEN OTHERS THEN
         DBMS_OUTPUT.PUT_LINE('Error : '||SQLERRM);
    END ETL_HELPER_PARSE;
    

提交回复
热议问题