Split column to multiple rows

别等时光非礼了梦想. 提交于 2019-11-27 15:20:20

And the correct answer is.

select Number, substr(
Site, 
instr(','||Site,',',1,seq),
instr(','||Site||',',',',1,seq+1) - instr(','||Site,',',1,seq)-1)  Site
from Sitetable,(select level seq from dual connect by level <= 100) seqgen
where instr(','||Site,',',1,seq) > 0
Conrad Frix

Did you Try Michael Sofaer's answer to How to best split csv strings in oracle 9i

create or replace function splitter_count(str in varchar2, delim in char) return int as
val int;
begin
  val := length(replace(str, delim, delim || ' '));
  return val - length(str); 
end;

create type token_list is varray(100) of varchar2(200);

CREATE or replace function tokenize (str varchar2, delim char) return token_list as
ret token_list;
target int;
i int;
this_delim int;
last_delim int;
BEGIN
  ret := token_list();
  i := 1;
  last_delim := 0;
  target := splitter_count(str, delim);
  while i <= target
  loop
    ret.extend();
    this_delim := instr(str, delim, 1, i);
    ret(i):= substr(str, last_delim + 1, this_delim - last_delim -1);
    i := i + 1;
    last_delim := this_delim;
  end loop;
  ret.extend();
  ret(i):= substr(str, last_delim + 1);
  return ret;
end;

------------Create Result Table-------------------------------------------

create table resulTable(

cnumber number,

Site varchar2(1000)

);

------------Create Splitter Procedure--------------------------------------

/Here I replaced numbers for example: 2-78 by s2ss78s for using
DBMS_UTILITY.comma_to_table(it doesn't work on numbers)
/

create or replace procedure split_list_to_rows(num number,plist varchar2) as

ptablen BINARY_INTEGER;

ptab DBMS_UTILITY.uncl_array;

begin

DBMS_UTILITY.comma_to_table (

list => replace(replace(CONCAT('s', plist),',',',s'),'-','ss'),

tablen => ptablen,

tab => ptab);

FOR i IN 1 .. ptablen LOOP

insert INTO resulTable VALUES (num,replace(ltrim(ptab(i),'s'),'ss','-'));

END LOOP;

END;

------------PL/SQL Block To Execute Procedure For Each Row-------------------

begin

for i in (select cnumber,Site from Sitetable)

loop

split_list_to_rows(i.cnumber,i.Site);

end loop;

end;

------------------------See The Result---------------------------------------

select * from resulTable;

I think you have a max limit of 100 comma separated values which is unnecessary, though probably not harmful in your case.

instead of

from Sitetable,(select level seq from dual connect by level <= 100) 

this should work for any number of values (level limited by the max number of commas present).

from Sitetable,(select level seq from dual connect by level <=  (select max((LENGTH(site)-LENGTH(REPLACE(site,',', '' ))) + 1) from sitetable)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!