Joyce,
Dưới đây là ba ví dụ:
1) Sử dụng dbms_utility.comma_to_table. Đây không phải là một quy trình có mục đích chung, vì các phần tử phải là số nhận dạng hợp lệ. Với một số thủ thuật bẩn thỉu, chúng tôi có thể làm cho nó hoạt động phổ biến hơn:
SQL> declare
2 cn_non_occuring_prefix constant varchar2(4) := 'zzzz';
3 mystring varchar2(2000):='a:sd:dfg:31456:dasd: :sdfsdf'; -- just an example
4 l_tablen binary_integer;
5 l_tab dbms_utility.uncl_array;
6 begin
7 dbms_utility.comma_to_table
8 ( list => cn_non_occuring_prefix || replace(mystring,':',','||cn_non_occuring_prefix)
9 , tablen => l_tablen
10 , tab => l_tab
11 );
12 for i in 1..l_tablen
13 loop
14 dbms_output.put_line(substr(l_tab(i),1+length(cn_non_occuring_prefix)));
15 end loop;
16 end;
17 /
a
sd
dfg
31456
dasd
sdfsdf
PL/SQL-procedure is geslaagd.
2) Sử dụng SQL của kết nối theo cấp độ. Nếu bạn từ 10g trở lên, bạn có thể sử dụng phương pháp kết nối theo cấp kết hợp với các biểu thức chính quy, như sau:
SQL> declare
2 mystring varchar2(2000):='a:sd:dfg:31456:dasd: :sdfsdf'; -- just an example
3 begin
4 for r in
5 ( select regexp_substr(mystring,'[^:]+',1,level) element
6 from dual
7 connect by level <= length(regexp_replace(mystring,'[^:]+')) + 1
8 )
9 loop
10 dbms_output.put_line(r.element);
11 end loop;
12 end;
13 /
a
sd
dfg
31456
dasd
sdfsdf
PL/SQL-procedure is geslaagd.
3) Một lần nữa sử dụng kết nối theo cấp độ của SQL, nhưng bây giờ kết hợp với SUBSTR / INSTR cũ tốt trong trường hợp bạn đang sử dụng phiên bản 9, giống như bạn:
SQL> declare
2 mystring varchar2(2000):='a:sd:dfg:31456:dasd: :sdfsdf'; -- just an example
3 begin
4 for r in
5 ( select substr
6 ( str
7 , instr(str,':',1,level) + 1
8 , instr(str,':',1,level+1) - instr(str,':',1,level) - 1
9 ) element
10 from (select ':' || mystring || ':' str from dual)
11 connect by level <= length(str) - length(replace(str,':')) - 1
12 )
13 loop
14 dbms_output.put_line(r.element);
15 end loop;
16 end;
17 /
a
sd
dfg
31456
dasd
sdfsdf
PL/SQL-procedure is geslaagd.
Bạn có thể xem thêm một số kỹ thuật như thế này, trong bài đăng blog này:http://rwijk.blogspot.com/2007/11/interval-based-row-generation.html
Hy vọng điều này sẽ hữu ích.
Trân trọng, Rob.
Để giải quyết nhận xét của bạn:
Ví dụ về việc chèn các giá trị được phân tách vào bảng chuẩn hóa.
Đầu tiên, hãy tạo các bảng:
SQL> create table csv_table (col)
2 as
3 select 'a,sd,dfg,31456,dasd,,sdfsdf' from dual union all
4 select 'a,bb,ccc,dddd' from dual union all
5 select 'zz,yy,' from dual
6 /
Table created.
SQL> create table normalized_table (value varchar2(10))
2 /
Table created.
Bởi vì bạn có vẻ quan tâm đến cách tiếp cận dbms_utility.comma_to_table, tôi đề cập đến nó ở đây. Tuy nhiên, tôi chắc chắn không khuyên bạn nên sử dụng biến thể này, vì số nhận dạng không ổn định và do quá trình xử lý từng hàng chậm.
SQL> declare
2 cn_non_occuring_prefix constant varchar2(4) := 'zzzz';
3 l_tablen binary_integer;
4 l_tab dbms_utility.uncl_array;
5 begin
6 for r in (select col from csv_table)
7 loop
8 dbms_utility.comma_to_table
9 ( list => cn_non_occuring_prefix || replace(r.col,',',','||cn_non_occuring_prefix)
10 , tablen => l_tablen
11 , tab => l_tab
12 );
13 forall i in 1..l_tablen
14 insert into normalized_table (value)
15 values (substr(l_tab(i),length(cn_non_occuring_prefix)+1))
16 ;
17 end loop;
18 end;
19 /
PL/SQL procedure successfully completed.
SQL> select * from normalized_table
2 /
VALUE
----------
a
sd
dfg
31456
dasd
sdfsdf
a
bb
ccc
dddd
zz
yy
14 rows selected.
Tôi khuyên bạn nên sử dụng biến thể SQL đơn này:
SQL> truncate table normalized_table
2 /
Table truncated.
SQL> insert into normalized_table (value)
2 select substr
3 ( col
4 , instr(col,',',1,l) + 1
5 , instr(col,',',1,l+1) - instr(col,',',1,l) - 1
6 )
7 from ( select ',' || col || ',' col from csv_table )
8 , ( select level l from dual connect by level <= 100 )
9 where l <= length(col) - length(replace(col,',')) - 1
10 /
14 rows created.
SQL> select * from normalized_table
2 /
VALUE
----------
a
a
zz
sd
bb
yy
dfg
ccc
31456
dddd
dasd
sdfsdf
14 rows selected.
Trân trọng, Rob.