Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

Cách tách chuỗi csv tốt nhất trong oracle 9i

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách thực hiện cài đặt Phiên bản Vision 12.2 EBS

  2. Ký tự thoát SQL trong Oracle (cho một '&')

  3. Giáng sinh đến sớm (Oracle 12.2)

  4. Sử dụng Oracle JDeveloper 12c với Cơ sở dữ liệu Oracle, Phần 1

  5. Phương pháp thiết lập các tham số NLS và các ưu tiên của chúng (Cơ sở dữ liệu Oracle)