Sql e几个小时。这个字符串失败了,比如'292183688062115,“Benedict Canyon Equities,Inc”,,,而不是返回6个值,而是返回4个值。@DeepakKumarPadhy-更新了一个稍微复杂的模式,所有逗号都改为逗号+字符。

Sql e几个小时。这个字符串失败了,比如'292183688062115,“Benedict Canyon Equities,Inc”,,,而不是返回6个值,而是返回4个值。@DeepakKumarPadhy-更新了一个稍微复杂的模式,所有逗号都改为逗号+字符。,sql,oracle,csv,plsql,Sql,Oracle,Csv,Plsql,e几个小时。这个字符串失败了,比如'292183688062115,“Benedict Canyon Equities,Inc”,,,而不是返回6个值,而是返回4个值。@DeepakKumarPadhy-更新了一个稍微复杂的模式,所有逗号都改为逗号+字符。伟大的Alex,现在它似乎工作正常,如果我的csv包含任何其他有线模式,请让我确定。工作起来很有魅力。非常感谢。可能帮我省了几个小时。 with text(text) as ( select '29218368,8062115," Benedi


e几个小时。这个字符串失败了,比如
'292183688062115,“Benedict Canyon Equities,Inc”,,
,而不是返回6个值,而是返回4个值。@DeepakKumarPadhy-更新了一个稍微复杂的模式,所有逗号都改为逗号+字符。伟大的Alex,现在它似乎工作正常,如果我的csv包含任何其他有线模式,请让我确定。工作起来很有魅力。非常感谢。可能帮我省了几个小时。
with text(text) as ( select '29218368,8062115," Benedict Canyon Equities, Inc",CLS,,FAX' from dual)
select level,
       trim(',' from 
                       case
                        when level in (1,2) then
                            regexp_substr(text, '(.*??)\,', 1, level)
                        when level = 3 then
                            regexp_substr(text, '"(.*??)"', 1, 1)
                        when level in (4,5) then
                            regexp_substr(text, '(.*??)\,', instr(text, '"', 1, 2), level -2) 
                        when level = 6 then       
                            regexp_substr(text, '\,([^\,]*)', instr(text, '"', 1, 2), 3)
                       end
            )
from text
connect by level <= 6
/* CAR   select car('hello,world,bla') from dual --> hello */
create or replace function car(PI_STR in varchar2,
                               PI_SEPARATOR in varchar2 default ',')
  return varchar2 is l_pos number;
begin
  l_pos := instr(PI_STR, PI_SEPARATOR);

  if l_pos > 0 then
    return substr(PI_STR, 1, l_pos - 1);
  end if;

  return PI_STR;
end;

/* CDR select cdr('hello,world,bla') from dual --> world,bla */
create or replace function cdr(PI_STR in varchar2,
                               PI_SEPARATOR in varchar2 default ',')
  return varchar2 is l_pos number;
begin
  l_pos := instr(PI_STR, PI_SEPARATOR);

  if l_pos > 0 then
    return substr(PI_STR, l_pos + length(PI_SEPARATOR));
  end if;

  return '';
end;
create or replace type csv_col is table of varchar2(4000);

create or replace function get_columns(PI_STR in varchar2,
                                       PI_SEPARATOR in varchar2,
                                       PI_ESC_CHAR in varchar2)
  return csv_col pipelined is l_car varchar2(4000);
l_cdr varchar2(4000);
l_car_esc varchar2(4000);
begin
  l_car := car(PI_STR, PI_SEPARATOR);
  l_cdr := cdr(PI_STR, PI_SEPARATOR);
  -- check for escape char
  l_car_esc := cdr(l_car, PI_ESC_CHAR);
  if l_car_esc is not null then
    l_car := l_car_esc || PI_SEPARATOR || car(l_cdr, PI_ESC_CHAR);
    l_cdr := cdr(cdr(l_cdr, PI_ESC_CHAR), PI_SEPARATOR);
  end if;
  loop
    if l_car is null and l_cdr is null then
      exit;
    end if;

    pipe row(l_car);
    l_car     := car(l_cdr, PI_SEPARATOR);
    l_cdr     := cdr(l_cdr, PI_SEPARATOR);
    l_car_esc := cdr(l_car, PI_ESC_CHAR);
    if l_car_esc is not null then
      l_car := l_car_esc || PI_SEPARATOR || car(l_cdr, PI_ESC_CHAR);
      l_cdr := cdr(cdr(l_cdr, PI_ESC_CHAR), PI_SEPARATOR);
      dbms_output.put_line(l_car);
      dbms_output.put_line(l_cdr);
    end if;
  end loop;
end;
select *
  from table(get_columns('29218368,8062115," Benedict Canyon Equities, Inc",CLS,,FAX',
                         ',',
                         '"'));
29218368
8062115
 Benedict Canyon Equities, Inc
CLS

FAX
var v_lastline varchar2(50);
exec :v_lastline := '29218368,8062115," Benedict Canyon Equities, Inc",CLS,,FAX';

select level as lvl,
  regexp_substr(:v_lastline, '("[^"]*"|[^,]+)', 1, level) as element
from dual
connect by level <= regexp_count(:v_lastline, '("[^"]*"|[^,]+)');

       LVL ELEMENT                                
---------- ----------------------------------------
         1 29218368                                
         2 8062115                                 
         3 " Benedict Canyon Equities, Inc"        
         4 CLS                                     
         5 FAX                                     
select level as lvl,
  replace(regexp_substr(replace(:v_lastline, ',', ',§'),
    '(§"[^"]*"|[^,]+)', 1, level), '§', null) as element
from dual
connect by regexp_substr(replace(:v_lastline, ',', ',§'),
  '(§"[^"]*"|[^,]+)', 1, level) is not null;

       LVL ELEMENT                                
---------- ----------------------------------------
         1 29218368                                
         2 8062115                                 
         3 " Benedict Canyon Equities, Inc"        
         4 CLS                                     
         5                                         
         6 FAX                                     
set serveroutput on
declare
  v_lastline varchar2(50);
  v_array sys.odcivarchar2list;
begin
  v_lastline := '29218368,8062115," Benedict Canyon Equities, Inc",CLS,,FAX';

  select trim(replace(replace(
    regexp_substr(replace(:v_lastline, ',', ',§'),
      '(§"[^"]*"|[^,]+)', 1, level), '§', null), '"', null))
  bulk collect into v_array
  from dual
  connect by regexp_substr(replace(:v_lastline, ',', ',§'),
    '(§"[^"]*"|[^,]+)', 1, level) is not null;

  dbms_output.put_line('Number of elements: ' || v_array.count);
  for i in 1..v_array.count loop
    dbms_output.put_line('Index ' || i || ' has: ' || v_array(i));
  end loop;
end;
/

Number of elements: 6
Index 1 has: 29218368
Index 2 has: 8062115
Index 3 has: Benedict Canyon Equities, Inc
Index 4 has: CLS
Index 5 has: 
Index 6 has: FAX
exec :v_lastline := '29218368,8062115," Benedict Canyon Equities, Inc",,,,,,,CLS,,,,,FAX,,,,,,,,,,,,,,,,,,INVOICE';
select level as lvl,
  replace(regexp_substr(replace(:v_lastline, ',', ',§'),
    '(§"[^"]*"|[^,]+)', 1, level), '§', null) as element
from dual
connect by regexp_substr(replace(:v_lastline, ',', ',§'),
  '(§"[^"]*"|[^,]+)', 1, level) is not null;

       LVL ELEMENT                                
---------- ----------------------------------------
         1 29218368                                
         2 8062115                                 
         3 " Benedict Canyon Equities, Inc"        
         4                                         
...
         9                                         
        10 CLS                                     
        11                                         
...
        14                                         
        15 FAX                                     
        16                                         
...
        32                                         
        33 INVOICE