欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  数据库

CSV to array

程序员文章站 2022-05-20 11:57:55
...

将CSV的字符串 截断成相应的 字符串值数组 PL/SQL jQuery CSV function csv_to_array (p_csv_line in varchar2, p_separator in varchar2 := g_default_separator) return t_str_arrayas type t_str_array as table of varchar2(4000); l_returnvalue t_str_a

将CSV的字符串
截断成相应的 字符串值数组 PL/SQL jQuery CSV
function csv_to_array (p_csv_line in varchar2,
                       p_separator in varchar2 := g_default_separator) return t_str_array
as
  type t_str_array as table of varchar2(4000);
  l_returnvalue      t_str_array     := t_str_array();--返回的字符串数组类型
  l_start_separator  pls_integer     := 0 ;
  l_stop_separator   pls_integer     := 0 ;
  l_length           pls_integer     := 0 ;--长度
  l_idx              binary_integer  := 0 ;
  l_quote_enclosed   boolean         := false ;
  l_offset           pls_integer     := 1 ;
begin

  /*

  Purpose:      convert CSV line to array of values

  Remarks:      based on code from http://www.experts-exchange.com/Database/Oracle/PL_SQL/Q_23106446.html

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

  */
  /*
  相应的CSV中的注意 就是关于 "" 中包含分隔符 ,的情况,需要通过标记 是否有双引号的 变量来进行扫描查找 
  同时保存三个扫描量:扫描开始位置(扫描头),扫描结束位置(扫描尾),扫描偏移量(用来标记扫描的偏移)
  */
  --获得长度
  l_length := length(p_csv_line) ;

  if l_length > 0 then
    loop
      --递增 标记的数据下标
      l_idx := l_idx + 1;

      l_quote_enclosed := false;
      --判断开始分割的 下一个字符是否是 "
      if substr(p_csv_line, l_start_separator + 1, 1) = '"' then
        --如果是 标记其 有双引号
        l_quote_enclosed := true;
        --设定 扫描偏移单位为 2
        l_offset := 2;
        --查找 下一个双引号的位置
        l_stop_separator := instr(p_csv_line, '"', l_start_separator + l_offset, 1);
      else
        --如果没有 双引号 
        --设定 扫描偏移单位为 1
        l_offset := 1;
        --查找 下一个 分割符 的位置
        l_stop_separator := instr(p_csv_line, p_separator, l_start_separator + l_offset, 1);
      end if;
      --如果 没有找到 扫描的下一个 位置
      if l_stop_separator = 0 then
        --设定 扫描的下一个位置为  总长度+1 从而推出循环
        l_stop_separator := l_length + 1;
      end if;
      --将 扫描得到的 值 保存到数组中
      l_returnvalue.extend;      
      l_returnvalue(l_idx) := substr(p_csv_line, l_start_separator + l_offset, (l_stop_separator - l_start_separator - l_offset));
      --如果扫描到头 就推出循环
      exit when l_stop_separator >= l_length;
      --如果有 双引号
      if l_quote_enclosed then
        --将扫描位置 +1 从而过滤掉"
        l_stop_separator := l_stop_separator + 1;
      end if ;
      --标记 扫描的开始位置 为 扫描到的位置
      l_start_separator := l_stop_separator;
    end loop;

  end if;
  -- 返回结果
  return l_returnvalue;

end csv_to_array;