塗抹ORACLE-第5章-SQL*Loader 之一千零一十一個怎麼辦(3)

junsansi發表於2009-12-30

5.3.7 提供了多個資料檔案,要匯入同一張表怎麼辦

  通常對於邏輯比較複雜的系統可能存在這種情況,因為匯出的資料來源於多個系統,因此可能提供給DBA的也是多個資料檔案。沒有關係,先不要急著報怨,像SQL*Loader 這麼有歷史底蘊的工具,什麼風雨沒見過,這種小 case ,人家早就已經預見到了,並不需要你執行多次載入,只需要在控制檔案中做適當配置即可。不過有一點非常重要,提供的資料檔案中的資料存放格式必須完全相同。

  下面簡單演示,之前老是用 BONUS ,這裡我們們換個表吧,新建一個 MANAGER 表:

    SQL>  CREATE TABLE MANAGER(

      2  MGRNO NUMBER,

      3  MNAME VARCHAR2(30),

      4  JOB VARCHAR2(30),

      5  REMARK VARCHAR2(4000));

    表已建立。

  有多個資料檔案,分別如下:

    10,SMITH,SALES MANAGER

    11,ALLEN.W,TECH MANAGER

    16,BLAKE,HR MANAGER

  示例程式碼儲存為資料檔案ldr_case8_1.dat。

    12,WARD,SERVICE MANAGER

    13,TURNER,SELLS DIRECTOR

    15,JAMES,HR DIRECTOR

  示例程式碼儲存為資料檔案ldr_case8_2.dat。

    17,MILLER,PRESIDENT

  示例程式碼儲存為資料檔案ldr_case8_3.dat。

  建立控制檔案,只需要指定多個 INFILE 引數即可,如下所示:

    LOAD DATA

    INFILE ldr_case8_1.dat

    INFILE ldr_case8_2.dat

    INFILE ldr_case8_3.dat

    TRUNCATE INTO TABLE MANAGER

    FIELDS TERMINATED BY ","

    (MGRNO,MNAME,JOB)

  示例程式碼儲存為控制檔案ldr_case8.ctl。

  執行 SQLLDR 命令:

    F:\oracle\script> SQLLDR SCOTT/TIGER CONTROL=LDR_CASE8.CTL

    SQL*Loader: Release 10.2.0.1.0 - Production on 星期四 3月 12 11:26:09 2009

    Copyright (c) 1982, 2007, Oracle.  All rights reserved.

    達到提交點 - 邏輯記錄計數 2

    達到提交點 - 邏輯記錄計數 3

    達到提交點 - 邏輯記錄計數 5

    達到提交點 - 邏輯記錄計數 6

    達到提交點 - 邏輯記錄計數 7

  SQL*Plus 中檢視匯入結果:

    SQL>  SELECT *FROM MANAGER;

    MGRNO  MNAME       JOB           REMARK

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

       10  SMITH       SALES  MANAGER

       11  ALLEN.W     TECH  MANAGER

       16  BLAKE       HR  MANAGER

       12  WARD        SERVICE  MANAGER

       13  TURNER      SELLS  DIRECTOR

       15  JAMES       HR  DIRECTOR

       17  MILLER      PRESIDENT

5.3.8 同一個資料檔案,要匯入不同表怎麼辦

  控制檔案提供了多種邏輯判斷方式,只要能把邏輯清晰地描述出來,SQL*Loader 就能按照指定的邏輯執行載入。

  舉個例子,待匯入的資料檔案如下:

    BON SMITH CLEAK     3904

    BON ALLEN SALER,M   2891

    BON WARD  SALER,"S" 3128

    BON KING  PRESIDENT 2523

    MGR 10 SMITH   SALES MANAGER

    MGR 11 ALLEN.W TECH MANAGER

    MGR 16 BLAKE   HR MANAGER

    TMP SMITH 7369 CLERK    800  20

    TMP ALLEN 7499 SALESMAN 1600 30

    TMP WARD  7521 SALESMAN 1250 30

    TMP JONES 7566 MANAGER  2975 20

  示例程式碼儲存為資料檔案ldr_case9.dat。

  需求是將以MGR開頭的記錄匯入MANAGER表,以BON開頭的記錄匯入BONUS表,其他記錄存入廢棄檔案中(不知道啥是廢棄檔案?向前翻看5.2.4小節)。

  建立控制檔案如下:

    LOAD DATA

    INFILE ldr_case9.dat

    DISCARDFILE ldr_case9.dsc

    TRUNCATE

     INTO TABLE BONUS

      WHEN TAB= ' BON '

      (TAB FILLER POSITION(1:3),

       ENAME POSITION(5:9) ,

       JOB POSITION(*+1:18),

       SAL POSITION(*+1) 

       )

     INTO TABLE MANAGER

      WHEN TAB =  ' MGR '

      (TAB FILLER POSITION(1:3),

       MGRNO POSITION(4:5) ,

       MNAME POSITION(7:13),

       JOB POSITION(*+1))

  示例程式碼儲存為控制檔案ldr_case9.ctl。

  雖然這個控制檔案看起來比之前的都要複雜,但只有一個新語法,即WHEN關鍵字,我們這裡通過WHEN來實現判斷,很容易理解。同時,指定了DISCARDFILE引數,以生成不滿足載入條件的廢棄檔案,如果你有心,不妨等執行完 SQLLDR 命令後檢視ldr_case9.dsc檔案和ldr_case9.log檔案。

  另外注意,控制檔案中WHEN邏輯判斷不支援OR關鍵字,因此如果你的判斷條件有多個,則只能通過AND連線,而不能直接使用OR。

  執行 SQLLDR 命令:

    F:\oracle\script> SQLLDR SCOTT/TIGER CONTROL=LDR_CASE9.CTL

    SQL*Loader: Release 10.2.0.1.0 - Production on 星期四 3月 12 20:50:16 2009

    Copyright (c) 1982, 2005, Oracle.  All rights reserved.

    達到提交點 - 邏輯記錄計數 10

  SQL*Plus 中檢視匯入結果:

    SQL>  SELECT * FROM BONUS;

    ENAME      JOB              SAL        COMM

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

    SMITH      CLEAK            3904

    ALLEN      SALER,M          2891

    WARD       SALER,"S"         3128

    KING       PRESIDENT        2523

    SQL>  Select * From Manager;

    MGRNO  MNAME     JOB       REMARK

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

    10  SMITH       SALES MANAGER

    11  ALLEN.W     TECH MANAGER

    16  BLAKE       HR MANAGER

  輕鬆實現,完全沒有難度嘛!

  回答完以上兩個怎麼辦後,如果你還能問出提供多個檔案怎樣匯入多張表之類問題,那你就是找上門來讓俺BS啊。

5.3.9 資料檔案前 N 行不想匯入怎麼辦

  假如某天你接到一項資料載入需求,使用者提供了一份100萬行的資料檔案,告訴你只導後50萬行,恭喜,你接到了一個正常的需求!

  實現的方式較多,比如修改資料檔案,只保留後50萬行(Windows 下藉助 Edit Plus 這類文字工具可以輕鬆實現,Linux/UNIX 下通過 tail 等命令也可以輕易實現),如果你人很懶,不想修改檔案,那正合 SQLLDR 胃口,人家早早地就提供好了SKIP引數專用於滿足此類需求。

  例如:提供資料檔案如下:

    SQL>  SELECT ENAME,MGR,JOB,SAL FROM EMP;

    ENAME             MGR  JOB                 SAL

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

    SMITH            7902  CLERK              800

    ALLEN            7698  SALESMAN         1600

    WARD             7698  SALESMAN         1250

    JONES            7839  MANAGER          2975

    MARTIN           7698  SALESMAN         1250

    BLAKE            7839  MANAGER          2850

    CLARK            7839  MANAGER          2450

    KING          PRESIDENT         5000

    TURNER           7698  SALESMAN         1500

    JAMES            7698  CLERK             950

    FORD             7566  ANALYST          3000

    MILLER           7782  CLERK             1300

  示例程式碼儲存為資料檔案ldr_case10.dat。

  相信不用我說,你也看出要做什麼了,前3行不匯入,從第4行開始載入,這裡建立控制檔案如下:

    LOAD DATA

    INFILE ldr_case10.dat

    TRUNCATE INTO TABLE BONUS

    (

    ENAME position(1:6),

    TCOL FILLER position(18:21),

    JOB position(23:31),

    SAL position(39:42)

    )

  示例程式碼儲存為控制檔案ldr_case10.ctl。

  執行 SQLLDR 命令:

    F:\oracle\script> SQLLDR SCOTT/TIGER CONTROL=LDR_CASE10.CTL SKIP =3

    SQL*Loader: Release 10.2.0.1.0 - Production on 星期一 3月 16 13:41:55 2009

    Copyright (c) 1982, 2007, Oracle.  All rights reserved.

    達到提交點 - 邏輯記錄計數 11

    達到提交點 - 邏輯記錄計數 12

  SQL*Plus 中檢視匯入結果:

    SQL>  SELECT * FROM BONUS;

    ENAME     JOB                    SAL      COMM

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

    SMITH       CLERK                800

    ALLEN       SALESMAN          1600

    WARD        SALESMAN          1250

    JONES       MANAGER           2975

    MARTIN      SALESMAN          1250

    BLAKE       MANAGER            2850

    CLARK       MANAGER            2450

    KING        PRESIDENT           5000

    TURNER      SALESMAN           1500

    JAMES       CLERK                950

    FORD        ANALYST            3000

    MILLER      CLERK               1300

  如果使用者要求較高,明確指定只載入第××~第××行的記錄(其實是好事,需求越明確越好),沒問題, SQLLDR 還有一個引數叫 LOAD ,配置LOAD引數即可輕鬆實現。

  這裡仍使用上述資料檔案,需求改為只匯入第4~9行的記錄,我們連控制檔案都不需要修改,只需要在執行 SQLLDR 時再加上 LOAD 引數即可:

    F:\oracle\script> SQLLDR SCOTT/TIGER CONTROL=LDR_CASE10.CTL SKIP=4  LOAD=6

    SQL*Loader: Release 10.2.0.1.0 - Production on 星期一 3月 16 13:45:38 2009

    Copyright (c) 1982, 2007, Oracle.  All rights reserved.

    達到提交點 - 邏輯記錄計數 6

  SQL*Plus 中檢視結果:

    SQL>  SELECT * FROM BONUS;

    ENAME      JOB                SAL        COMM

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

    SMITH       CLERK            800

    ALLEN       SALESMAN        1600

    WARD        SALESMAN        1250

    JONES       MANAGER         2975

    MARTIN      SALESMAN        1250

    BLAKE       MANAGER         2850

=================================================
全書目錄:http://space.itpub.net/7607759/viewspace-622699
樣書預覽:http://space.itpub.net/7607759/viewspace-622515
馬上購買:http://www.china-pub.com/196252

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7607759/viewspace-623965/,如需轉載,請註明出處,否則將追究法律責任。

相關文章