日期:2014-05-17  浏览次数:20809 次

新手求教数据分割插入问题

目前有一张源表,里面有几千条类似这样的数据
"5-4",21,benben,"[ a, 509, 0, 29 ]"
"5-9",20,birdegg,"[ c,7,5,3,2,a, 509, 0, 29 ]"
"5-n",20,birdegg,"[ 1,2,3,4,5,6....n]"

5-后面的数字不固定,n为结果表的最大列数,不知道能否实现如下功能
drop table temp
create table temp (a1 varchar(100),a2 varchar(100),a3 varchar(100),a4 varchar(100),a5 varchar(100),a6 varchar(100),a7 varchar(100),a8 varchar(100),a9 varchar(100),a10 varchar(100),a11 varchar(100),a12 varchar(100))
insert into temp 
select '5-4',21,'benben','a', 509, 0, 29,null,null,null,null,null from dual
insert into temp 
select '5-9',20,'birdegg','c',7,5,3,2,'a', 509, 0, 29 from dual

因为不确定n有多少行,如果多一列,建表语句就要多建一行。 

首先要找到字符串里面最大列数,然后对后面的影号里进行分割成列,用NULL补足插入结果表TEMP~不知道自定义函数能否实现。。急。。 


------解决方案--------------------
drop table t;
create table t(a varchar2(100));
insert into t (A)
values ('"5-4",21,benben,"[a,509,0,29]"');

insert into t (A)
values ('"5-9",20,birdegg,"[c,7,5,3,2,a,509,0,29]"');

insert into t (A)
values ('"5-12",19,birdkk,"[c1,7a,5,3,2,a,5091,40,229]"');
commit;


declare
  max_col     number := -1;
  v_count     number;
  v_str       varchar2(100);
begin
  select max(to_number(regexp_replace(t.a, '.*-(\d+)".*', '\1')))
    into max_col
    from t;
  for i in (select a,
                   regexp_replace(t.a, '"
------解决方案--------------------
\[
------解决方案--------------------
]', '') c,
                   regexp_replace(t.a, '.*\[(.*)].*', '\1') d
              from t) loop
    v_count := max_col - regexp_count(i.d, ',') - 1;  
    for j in (select regexp_substr(i.c, '+[^,$]+', 1, LEVEL) str
                from dual
              connect by level <= regexp_count(i.c, ',') + 1) loop
      begin
        v_str := v_str 
------解决方案--------------------
 to_number(j.str) 
------解决方案--------------------
 ',';
      exception
        when others then
          v_str := v_str 
------解决方案--------------------
 ''''