Oracle SQL Loader


一:SQL Loader 的特点
Oracle自己带了很多的工具可以用来进行数据的迁移、备份和恢复等工作。但是每个工具都有自己的特点。
比如说exp和imp可以对数据库中的数据进行导出和导出的工作,是一种很好的数据库备份和恢复的工具,因此主要用在数据库的热备份和恢复方面。有着速度快,使用简单,快捷的优点;同时也有一些缺点,比如在不同版本数据库之间的导出、导入的过程之中,总会出现这样或者那样的问题,这个也许是oracle公司自己产品的兼容性的问题吧。
sql loader 工具却没有这方面的问题,它可以把一些以文本格式存放的数据顺利的导入到oracle数据库中,是一种在不同数据库之间进行数据迁移的非常方便而且通用的工具。缺点就速度比较慢,另外对blob等类型的数据就有点麻烦了。

二. sqlldr 帮助:
C:/Documents and Settings/David>sqlldr
SQL*Loader: Release 10.2.0.1.0 - Production on 星期四 7月 2 08:54:06 2009
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
用法: SQLLDR keyword=value [,keyword=value,...]
有效的关键字:
    userid -- ORACLE 用户名/口令
   control -- 控制文件名
       log -- 日志文件名
       bad -- 错误文件名
      data -- 数据文件名
   discard -- 废弃文件名
discardmax -- 允许废弃的文件的数目         (全部默认)
      skip -- 要跳过的逻辑记录的数目  (默认 0)
      load -- 要加载的逻辑记录的数目  (全部默认)
    errors -- 允许的错误的数目         (默认 50)
      rows -- 常规路径绑定数组中或直接路径保存数据间的行数
               (默认: 常规路径 64, 所有直接路径)
  bindsize -- 常规路径绑定数组的大小 (以字节计)  (默认 256000)
    silent -- 运行过程中隐藏消息 (标题,反馈,错误,废弃,分区)
    direct -- 使用直接路径                     (默认 FALSE)
   parfile -- 参数文件: 包含参数说明的文件的名称
  parallel -- 执行并行加载                    (默认 FALSE)
      file -- 要从以下对象中分配区的文件
skip_unusable_indexes -- 不允许/允许使用无用的索引或索引分区  (默认 FALSE)
skip_index_maintenance -- 没有维护索引, 将受到影响的索引标记为无用  (默认 FALSE)
commit_discontinued -- 提交加载中断时已加载的行  (默认 FALSE)
  readsize -- 读取缓冲区的大小               (默认 1048576)
external_table -- 使用外部表进行加载; NOT_USED, GENERATE_ONLY, EXECUTE  (默认 NO
T_USED)
columnarrayrows -- 直接路径列数组的行数  (默认 5000)
streamsize -- 直接路径流缓冲区的大小 (以字节计)  (默认 256000)
multithreading -- 在直接路径中使用多线程
resumable -- 启用或禁用当前的可恢复会话  (默认 FALSE)
resumable_name -- 有助于标识可恢复语句的文本字符串
resumable_timeout -- RESUMABLE 的等待时间 (以秒计)  (默认 7200)
date_cache -- 日期转换高速缓存的大小 (以条目计)  (默认 1000)
PLEASE NOTE: 命令行参数可以由位置或关键字指定
。前者的例子是 ''sqlload
scott/tiger foo''; 后一种情况的一个示例是 ''sqlldr control=foo
userid=scott/tiger''.位置指定参数的时间必须早于
但不可迟于由关键字指定的参数。例如,
允许 ''sqlldr scott/tiger control=foo logfile=log'', 但是
不允许 ''sqlldr scott/tiger control=foo log'', 即使
参数 ''log'' 的位置正确。

三, SQL LOADER 实例

创建表:test_load,
sql>create table test_load(id number(10),uname varchar2(20), phone varchar2(20));
控制文件:d:/loader.ctl
load data
infile ''d:/datafile.txt''
append into table test_load
fields terminated by "," optionally enclosed by ''"''
( id, uname, phone )

数据文件:D:/datafile.txt
001,"david",0551-1234567
002,"dave",0551-7654311
sqlloader命令:
SQL>sqlldr ''sys/admin AS SYSDBA'' control=D:/loader.ctl log=d:/a.log
SQL*Loader: Release 10.2.0.1.0 - Production on 星期四 7月 2 09:40:42 2009
Copyright (c) 1982, 2005, Oracle.  All rights reserved.
达到提交点 - 逻辑记录计数 1
达到提交点 - 逻辑记录计数 2
SQL> select * from test2;
     EMPNO ENAME             SAL     DEPTNO
---------- ---------- ---------- ----------
     10002 Frank             500         20
     10001 Scott            1000         40

四, 控制文件详解
   加载可变长度或指定长度的记录,"*" 代表数据文件与此文件同名,即在后面使用BEGINDATA段来标识数据。
  如:
  LOAD DATA
  INFILE *
  INTO TABLE load_delimited_data
  FIELDS TERMINATED BY "," OPTIONALLY ENCLOSED BY ''"''
  TRAILING NULLCOLS
  ( data1,
  data2
  )
  BEGINDATA
  11111,AAAAAAAAAA
  22222,"A,B,C,D,"
  下面是导入固定位置(固定长度)数据示例:
  LOAD DATA
  INFILE *
  INTO TABLE load_positional_data
  ( data1 POSITION(1:5),
  data2 POSITION(6:15)
  )
  BEGINDATA
  11111AAAAAAAAAA
  22222BBBBBBBBBB
  跳过数据行:
  可以用 "SKIP n" 关键字来指定导入时可以跳过多少行数据。如:
  LOAD DATA
  INFILE *
  INTO TABLE load_positional_data
  SKIP 5
  ( data1 POSITION(1:5),
  data2 POSITION(6:15)
  )
  BEGINDATA
  11111AAAAAAAAAA
  22222BBBBBBBBBB
  导入数据时修改数据:
  在导入数据到数据库时,可以修改数据。注意,这仅适合于常规导入,并不适合 direct导入方式.如:
  LOAD DATA
  INFILE *
  INTO TABLE modified_data
  ( rec_no "my_db_sequence.nextval",
  region CONSTANT ''31'',
  time_loaded "to_char(SYSDATE, ''HH24:MI'')",
  data1 POSITION(1:5) ":data1/100",
  data2 POSITION(6:15) "upper(:data2)",
  data3 POSITION(16:22)"to_date(:data3, ''YYMMDD'')"
  )
  BEGINDATA
  11111AAAAAAAAAA991201
  22222BBBBBBBBBB990112
  LOAD DATA
  INFILE ''mail_orders.txt''
  BADFILE ''bad_orders.txt''
  APPEND
  INTO TABLE mailing_list
  FIELDS TERMINATED BY ","
  ( addr,
  city,
  state,
  zipcode,
  mailing_addr "decode(:mailing_addr, null, :addr, :mailing_addr)",
  mailing_city "decode(:mailing_city, null, :city, :mailing_city)",
  mailing_state
  )
  将数据导入多个表:
  如:
  LOAD DATA
  INFILE *
  REPLACE
  INTO TABLE emp
  WHEN empno != '' ''
  ( empno POSITION(1:4) INTEGER EXTERNAL,
  ename POSITION(6:15) CHAR,
  deptno POSITION(17:18) CHAR,
  mgr POSITION(20:23) INTEGER EXTERNAL
  )
  INTO TABLE proj
  WHEN projno != '' ''
  ( projno POSITION(25:27) INTEGER EXTERNAL,
  empno POSITION(1:4) INTEGER EXTERNAL
  )
  导入选定的记录:
  如下例: (01) 代表第一个字符, (30:37) 代表30到37之间的字符:
  LOAD DATA
  INFILE ''mydata.dat'' BADFILE ''mydata.bad'' DISCARDFILE ''mydata.dis''
  APPEND
  INTO TABLE my_selective_table
  WHEN (01) <> ''H'' and (01) <> ''T'' and (30:37) = ''19991217''
  (
  region CONSTANT ''31'',
  service_key POSITION(01:11) INTEGER EXTERNAL,
  call_b_no POSITION(12:29) CHAR
  )
  导入时跳过某些字段:
  可用 POSTION(x:y) 来分隔数据. 在Oracle8i中可以通过指定 FILLER 字段实现。FILLER 字段用来跳过、忽略导入数据文件中的字段.如:
  LOAD DATA
  TRUNCATE INTO TABLE T1
  FIELDS TERMINATED BY '',''
  ( field1,
  field2 FILLER,
  field3
  )
  导入多行记录:
  可以使用下面两个选项之一来实现将多行数据导入为一个记录:
  CONCATENATE: - use when SQL*Loader should combine the same number of physical records together to form one logical record.
  CONTINUEIF - use if a condition indicates that multiple records should be treated as one. Eg. by having a ''#'' character in column 1.

五, 补充知识
  Unloader这样的工具,Oracle 没有提供将数据导出到一个文件的工具。但是,我们可以用SQL*Plus的select 及 format 数据来输出到一个文件:
  set echo off newpage 0 space 0 pagesize 0 feed off head off trimspool on
  spool oradata.txt
  select col1 || '','' || col2 || '','' || col3
  from tab1
  where col2 = ''XYZ'';
  spool off
  另外,也可以使用使用 UTL_FILE PL/SQL 包处理:
  rem Remember to update initSID.ora, utl_file_dir=''c:/oradata'' parameter
  declare
  fp utl_file.file_type;
  begin
  fp := utl_file.fopen(''c:/oradata'',''tab1.txt'',''w'');
  utl_file.putf(fp, ''%s, %s/n'', ''TextField'', 55);
  utl_file.fclose(fp);
  end;
  
  当然你也可以使用第三方工具,如SQLWays ,TOAD for Quest等。

  SQL*Loader 数据的提交:
  一般情况下是在导入数据文件数据后提交的。
  ���可以通过指定 ROWS= 参数来指定每次提交记录数。
  提高 SQL*Loader 的性能:
  1) 一个简单而容易忽略的问题是,没有对导入的表使用任何索引和/或约束(主键)。如果这样做,甚至在使用ROWS=参数时,会很明显降低数据库导入性能。
  2) 可以添加 DIRECT=TRUE来提高导入数据的性能。当然,在很多情况下,不能使用此参数。
  3) 通过指定 UNRECOVERABLE选项,可以关闭数据库的日志。这个选项只能和 direct 一起使用。
  4) 可以同时运行多个导入任务.
  常规导入与direct导入方式的区别:
  常规导入可以通过使用 INSERT语句来导入数据。Direct导入可以跳过数据库的相关逻辑(DIRECT=TRUE),而直接将数据导入到数据文件中。

相关内容