Home  >  Article  >  Database  >  lob to csv

lob to csv

WBOY
WBOYOriginal
2016-06-07 14:55:001147browse

将相应的 大型对象LOB类型数据转为相应的CSV格式 返回 ,采用了piplined 的方式,也就是 运行出一条数据 就返回一条 ,不是全部都执行完了 再返回的形式 PL/SQL lob-to-csv piplined function clob_to_csv (p_csv_clob in clob, p_separator in varchar2 := g

将相应的 大型对象LOB类型数据转为相应的CSV格式 返回 ,采用了piplined 的方式,也就是 运行出一条数据 就返回一条 ,不是全部都执行完了 再返回的形式  PL/SQL lob-to-csv piplined
function clob_to_csv (p_csv_clob in clob,
                      p_separator in varchar2 := g_default_separator,
                      p_skip_rows in number := 0) return t_csv_tab pipelined
as
  l_line_separator         varchar2(2) := chr(13) || chr(10);--行的 分割符号 \r\n 
  l_last                   pls_integer;--上一次的扫描位置
  l_current                pls_integer;--这一次的扫描位置
  l_line                   varchar2(32000);
  l_line_number            pls_integer := 0;
  l_from_line              pls_integer := p_skip_rows + 1;
  l_line_array             t_str_array;
  l_row                    t_csv_line := t_csv_line (null, null,  -- line number, line raw
                                                     null, null, null, null, null, null, null, null, null, null,   -- lines 1-10
                                                     null, null, null, null, null, null, null, null, null, null);  -- lines 11-20
begin

  /*

  Purpose:      convert clob to CSV

  Remarks:      based on code from http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:1352202934074
                              and  http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:744825627183

  Who     Date        Description
  ------  ----------  --------------------------------
  MBR     31.03.2010  Created
  fartpig 07.03.2011  noted
  */

  -- If the file has a DOS newline (cr+lf), use that: 如果文件时DOS的格式就是用 \r\n
  -- If the file does not have a DOS newline, use a Unix newline (lf) 如果不是就采用 unix标准 \n
  -- 通过检索 \r\n 是否存在 
  if (nvl(dbms_lob.instr(p_csv_clob, l_line_separator, 1, 1),0) = 0) then
    l_line_separator := chr(10);
  end if;

  l_last := 1;--设定上一次扫描位置为 1 

  loop
    --检索 当前分割符号的位置
    --为了能够顺利的将文件读完 需要 将传入的 LOB结尾加上一个 分割符号
    l_current := dbms_lob.instr (p_csv_clob || l_line_separator, l_line_separator, l_last, 1);
    --当 没有找到时候 退出
    exit when (nvl(l_current,0) = 0);
    --递增  行号
    l_line_number := l_line_number + 1;
    
    if l_from_line <= l_line_number then
      --通过 上一次的标记和这一次的标记 获得相应的 子值
      --注意这里的参数 顺序和 instr不同 ,偏移量和长度 是反过来的
      l_line := dbms_lob.substr(p_csv_clob || l_line_separator, l_current - l_last + 1, l_last);
      --l_line := replace(l_line, l_line_separator, '');
      --将得到的 子值的 \r\n 替换掉
      l_line := replace(l_line, chr(10), '');
      l_line := replace(l_line, chr(13), '');
      --调用相应的 csv to array  API来处理 得到这个行 的结果数组
      l_line_array := csv_to_array (l_line, p_separator);
      --将获得的值 进行那个封装到 记录中 通过pip row返回
      l_row.line_number := l_line_number;
      l_row.line_raw := substr(l_line,1,4000);
      l_row.c001 := get_array_value (l_line_array, 1);
      l_row.c002 := get_array_value (l_line_array, 2);
      l_row.c003 := get_array_value (l_line_array, 3);
      l_row.c004 := get_array_value (l_line_array, 4);
      l_row.c005 := get_array_value (l_line_array, 5);
      l_row.c006 := get_array_value (l_line_array, 6);
      l_row.c007 := get_array_value (l_line_array, 7);
      l_row.c008 := get_array_value (l_line_array, 8);
      l_row.c009 := get_array_value (l_line_array, 9);
      l_row.c010 := get_array_value (l_line_array, 10);
      l_row.c011 := get_array_value (l_line_array, 11);
      l_row.c012 := get_array_value (l_line_array, 12);
      l_row.c013 := get_array_value (l_line_array, 13);
      l_row.c014 := get_array_value (l_line_array, 14);
      l_row.c015 := get_array_value (l_line_array, 15);
      l_row.c016 := get_array_value (l_line_array, 16);
      l_row.c017 := get_array_value (l_line_array, 17);
      l_row.c018 := get_array_value (l_line_array, 18);
      l_row.c019 := get_array_value (l_line_array, 19);
      l_row.c020 := get_array_value (l_line_array, 20);

      pipe row (l_row);

    end if;
    --将使用当前的扫描位置加上行的分割符号 来替换 上一次的扫描位置 
    l_last := l_current + length (l_line_separator);

  end loop;

  return;

end clob_to_csv;
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn