Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1208010
  • 博文数量: 350
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 5668
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-23 17:53
文章分类

全部博文(350)

文章存档

2013年(350)

分类: Oracle

2013-04-10 11:26:07

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
马上购买:
阅读(2190) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~