使用ORACLE外部表格裝載複雜資料

來源:互聯網
上載者:User

標籤:

原文:http://www.oracle.com/technetwork/issue-archive/2013/13-jan/o13asktom-1886639.html


I am using SQL Loader to load data into tables from a flat file. Some sample data in the file might be:

我打算使用SQL Loader裝載來自一般檔案資料。範例資料如下:


12,smith,[email protected]@1234567 @@876556612,1200
14,John,[email protected]@[email protected]@56789 @@[email protected]@[email protected]@[email protected]@23456,1345



The field values are empno, empname, phone numbers, and salary. The table structures are

表結構如下:


create table emp ( empno number(5) primary key, ename varchar2(10), Sal number(10,2) )
create table emp_contact ( empno references emp, phone_no number(10) )


I want to insert the data into the emp and emp_contact tables. I don’t know how many values for phone_no the file contains (the number of values for phone_no is not fixed). How do I insert the data into the tables?
我想將以上資料分別裝入2個表中: emp和emp_contact
問題是:我無法確定第三列(電話號碼)有多少個,此列不固定。我將如何將資料裝載進表?


這個問題很狡猾,看上去我們必須將第三列拆成多行插入。
對於號稱“ 21世紀神奇資料裝載工具”--SQL Loader 來講也無法直接實現!!!
此處,我建議使用21世紀資料裝載工具--外部表格 解決。思路是:將一般檔案裝入外部表格,然後通過編寫SQL進行拆分,最後按特定插入規則一次性插入指定表中。
下面,看我示範:
--1)進行資料裝載
create or replace directory my_dir as ‘/home/tkyte‘
/


CREATE TABLE et
 ( "EMPNO" VARCHAR2(10),
   "ENAME" VARCHAR2(20),
   "TELNOS" VARCHAR2(1000),
   "SAL" VARCHAR2(10) )
 ORGANIZATION external
 (
   TYPE oracle_loader
   DEFAULT DIRECTORY MY_DIR
   ACCESS PARAMETERS
   (
     RECORDS DELIMITED BY NEWLINE CHARACTERSET US7ASCII
     BADFILE ‘MY_DIR‘:‘t.bad‘
     LOGFILE ‘t.log_xt‘
     READSIZE 1048576
     FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY ‘"‘ LDRTRIM
     MISSING FIELD VALUES ARE NULL
     REJECT ROWS WITH ALL NULL FIELDS
     (
       "EMPNO" CHAR(255)
         TERMINATED BY "," OPTIONALLY ENCLOSED BY ‘"‘,
       "ENAME" CHAR(255)
         TERMINATED BY "," OPTIONALLY ENCLOSED BY ‘"‘,
       "TELNOS" CHAR(1000)
         TERMINATED BY "," OPTIONALLY ENCLOSED BY ‘"‘,
       "SAL" CHAR(255)
         TERMINATED BY "," OPTIONALLY ENCLOSED BY ‘"‘
     )
   )
   location
   (
     ‘t.dat‘
   )
 )
/


SQL> select * from et;


EMPNO  ENAME   TELNOS                                          SAL
—————  —————   —————————————————————————————————————————————   ————
12     smith   [email protected]@[email protected]@876556612                     1200
14     John    [email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@23456   1345


--2)編寫拆分SQL
SQL> select empno, ename, sal, i,
       substr( tnos,
               instr( tnos, ‘@@‘, 1, i )+2,
               instr( tnos, ‘@@‘, 1, i+1 )
                 -instr( tnos, ‘@@‘, 1, i) - 2 ) tno
  from (
select to_number(et.empno) empno,
       et.ename,
       to_number(et.sal) sal,
       column_value i,
       ‘@@‘||et.telnos||‘@@‘ tnos
  from et,
       table( cast( multiset(
          select level
            from dual
         connect by level <=
            (length(et.telnos)
               -length(replace(et.telnos,‘@@‘,‘‘)))/2+1 )
             as sys.odciNumberList ) )
       )
/


EMPNO  ENAME    SAL    I  TNO
—————  —————   ————   ——  ———————
   12  smith   1200    1  1234556
   12  smith   1200    2  1234567
   12  smith   1200    3  876556612
   14  John    1345    1  1234
   14  John    1345    2  4567
   14  John    1345    3  56789
   14  John    1345    4  12345
   14  John    1345    5  45778
   14  John    1345    6  34566
   14  John    1345    7  23456


10 rows selected.


--注意:這裡使用了cast multiset文法,column_value是TABLE(odciNumberList)中一列




--3)編寫插入SQL
SQL> create table emp
  2  ( empno number primary key,
  3    ename varchar2(10),
  4    sal   number
  5  );
Table created.


SQL> create table emp_contact
  2  ( empno    number references emp,
  3    phone_no number
  4  );
Table created.
\
SQL> insert all
when (i = 1) then into emp (empno,ename,sal) values (empno,ename,sal)
when (i > 0) then into emp_contact(empno,phone_no) values (empno,tno)
select empno, ename, sal, i,
       substr( tnos,
               instr( tnos, ‘@@‘, 1, i )+2,
               instr( tnos, ‘@@‘, 1, i+1 )
                 -instr( tnos, ‘@@‘, 1, i) - 2 ) tno
  from (
select to_number(et.empno) empno,
       et.ename,
       to_number(et.sal) sal,
       column_value i,
       ‘@@‘||et.telnos||‘@@‘ tnos
  from et,
       table( cast( multiset(
          select level
            from dual
         connect by level <=
            (length(et.telnos)
               -length(replace(et.telnos,‘@@‘,‘‘)))/2+1 )
             as sys.odciNumberList ) )
       )
/
12 rows created.


SQL> select * from emp;


EMPNO  ENAME    SAL
—————  ——————  —————
   12  smith   1200
   14  John    1345


SQL> select * from emp_contact;


EMPNO    PHONE_NO
———————  —————————
   12     1234556
   12     1234567
   12   876556612
   14        1234
   14        4567
   14       56789
   14       12345
   14       45778
   14       34566
   14       23456


10 rows selected.


------------------------------------

Dylan    Presents.




使用ORACLE外部表格裝載複雜資料

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.