转自:http://blog.chinaunix.net/uid-23622436-id-2394093.html

一:在 Oracle 数据库中,我们通常在不同数据库的表间记录进行复制或迁移时会用以下几种方法:

1. A 表的记录导出为一条条分号隔开的 insert 语句,然后执行插入到 B 表中

2. 建立数据库间的 dblink,然后用 create table B as select * from A@dblink where ...,或 insert into B select * from A@dblink where ...

3. exp A 表,再 imp 到 B 表,exp 时可加查询条件

4. 程序实现 select from A ..,然后 insert into B ...,也要分批提交
5. 再就是本篇要说到的 Sql Loader(sqlldr) 来导入数据,效果比起逐条 insert 来很明显

第 1 种方法在记录多时是个噩梦,需三五百条的分批提交,否则客户端会死掉,而且导入过程很慢。如果要不产生 REDO 来提高 insert into 的性能,就要下面那样做:

  1. alter table B nologging;
  2. insert /* +APPEND */ into B(c1,c2) values(x,xx);
  3. insert /* +APPEND */ into B select * from A@dblink where .....;

好 啦,前面简述了 Oracle 中数据导入导出的各种方法,我想一定还有更高明的。下面重点讲讲 Oracle  的 Sql Loader (sqlldr) 的用法。

二:在命令行下执行 Oracle  的 sqlldr 命令,可以看到它的详细参数说明,要着重关注以下几个参数:

userid -- Oracle 的 username/password[@servicename](远程:username/password@IP:PORT/servicename)

control -- 控制文件,可能包含表的数据

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

log -- 记录导入时的日志文件,默认为 控制文件(去除扩展名).log

bad -- 坏数据文件,默认为 控制文件(去除扩展名).bad

data -- 数据文件,一般在控制文件中指定。用参数控制文件中不指定数据文件更适于自动操作

errors -- 允许的错误记录数,可以用他来控制一条记录都不能错

rows -- 多少条记录提交一次,默认为 64

skip -- 跳过的行数,比如导出的数据文件前面几行是表头或其他描述

还有更多的 sqlldr 的参数说明请参考:sql loader的用法

用例子来演示 sqlldr 的使用,有两种使用方法:

1. 只使用一个控制文件,在这个控制文件中包含数据

2. 使用一个控制文件(作为模板) 和一个数据文件

一般为了利于模板和数据的 分离,以及程序的不同分工会使用第二种方式,所以先来看这种用法。数据文件可以是 CSV 文件或者以其他分割符分隔的,数据文件可以用 PL/SQL Developer 或者 Toad 导出,也可以用 SQL *Plus 的  spool 格式化产出,或是 UTL_FILE 包生成。另外,用 Toad 还能直接生成包含数据的控制文件。

首先,假定有这么一个表 users,并插入五条记录:

  1. create table users(
  2. user_id number,           --用户 ID
  3. user_name varchar2(50),   --用户名
  4. login_times number,       --登陆次数
  5. last_login date           --最后登录日期
  6. )
  1. insert into users values(1,'Unmi',3,sysdate);
  2. insert into users values(2,NULL,5,to_date('2008-10-15','YYYY-MM-DD'));
  3. insert into users values(3,'隔叶黄莺 ',8,to_date('2009-01-02','YYYY-MM-DD'));
  4. insert into users values(4,'Kypfos',NULL,NULL);
  5. insert into users values(5,'不知秋 ',1,to_date('2008-12-23','YYYY-MM-DD'));

第 二种方式: 使用一个控制文件(作为模板) 和一个数据文件

1) 建立数据文件,我们这里用 PL/SQL Developer 导出表 users 的记录为 users_data.csv 文件,内容如下:

  1. "   ","USER_ID","USER_NAME","LOGIN_TIMES","LAST_LOGIN"
  2. "1","1","Unmi","3","2009-1-5 20:34:44"
  3. "2","2","","5","2008-10-15"
  4. "3","3","隔叶黄莺","8","2009-1-2"
  5. "4","4","Kypfos","",""
  6. "5","5","不知秋","1","2008-12-23"

2) 建立一个控制文件 users.ctl,内容如下:

  1. OPTIONS (skip=1,rows=128) -- sqlldr 命令显示的 选项可以写到这里边来,skip=1 用来跳过数据中的第一行
  2. LOAD DATA
  3. INFILE "users_data.csv" --指定外部数据文件,可以写多 个 INFILE "another_data_file.csv" 指定多个数据文件
  4. --这里还可以使 用 BADFILE、DISCARDFILE 来指定坏数据和丢弃数据的文件,
  5. truncate --操作类型,用 truncate table 来清除表中原有 记录
  6. INTO TABLE users -- 要插入记录的表
  7. Fields terminated by "," -- 数据中每行记录用 "," 分隔
  8. Optionally enclosed by '"' -- 数据中每个字段用 '"' 框起,比如字段中有 "," 分隔符时
  9. trailing nullcols --表的字段没有对应的值时允 许为空
  10. (
  11. virtual_column FILLER, --这是一个虚拟字段,用来跳 过由 PL/SQL Developer 生成的第一列序号
  12. user_id number, --字段可以指定类型,否则认 为是 CHARACTER 类型, log 文件中有显示
  13. user_name,
  14. login_times,
  15. last_login DATE "YYYY-MM-DD HH24:MI:SS" -- 指定接受日期的格式,相当用 to_date() 函数转换
  16. )

说 明:在操作类型 truncate 位置可用以下中的一值:

1) insert     --为缺省方式,在数据装载开始时要求表为空

2) append  --在表中追加新记录

3) replace  --删除旧记录(用 delete from table 语句),替换成新装载的记录

4) truncate --删除旧记录(用 truncate table 语句),替换成新装载的记录

3) 执行命令:

sqlldr dbuser/dbpass@dbservice control=users.ctl

sqlldr dbuser/dbpass@ip:port/dbservice control = users.ctl

在 dbservice 指示的数据库的表 users 中记录就和数据文件中的一样了。

执行完 sqlldr 后希望能留意一下生成的几个文件,如 users.log 日志文件、users.bad 坏数据文件等。特别是要看看日志文件,从中可让你更好的理解 Sql Loader,里面有对控制文件的解析、列出每个字段的类型、加载记录的统计、出错原因等信息。

第二种方式,只使用一个控制文件 在这个控制文件中包含数据(这种方式没什么用,不建议使用

1) 把 users_data.cvs 中的内容补到 users.ctl 中,并以 BEGINDATA 连接,还要把 INFILE "users_data.csv" 改为 INFILE *。同时为了更大化的说明问题,把数据处理了一下。此时,完整的 users.ctl 文件内容是:

  1. OPTIONS (skip=1,rows=128) -- sqlldr 命令显示的 选项可以写到这里边来,skip=1 用来跳过数据中的第一行
  2. LOAD DATA
  3. INFILE *  -- 因为数据同控制文件在一 起,所以用 * 表示
  4. append    -- 这里用 了 append 来操作,在表 users 中附加记录
  5. INTO TABLE users
  6. when LOGIN_TIMES<>'8'  -- 还可以用 when 子 句选择导入符合条件的记录
  7. Fields terminated by ","
  8. trailing nullcols
  9. (
  10. virtual_column FILLER, --跳过 由 PL/SQL Developer 生成的第一列序号
  11. user_id "user_seq.nextval", --这一列直接取序列的下一值,而不用数据中提供的值
  12. user_name " 'Hi' || upper(:user_name)",--,还能用SQL函数或运算对数据进行加工处理
  13. login_times terminated by ",", NULLIF(login_times='NULL') --可为列单独指定分隔符
  14. last_login DATE "YYYY-MM-DD HH24:MI:SS" NULLIF (last_login="NULL") -- 当字段为"NULL"时就是 NULL
  15. )
  16. BEGINDATA --数据从这里开始
  17. ,USER_ID,USER_NAME,LOGIN_TIMES,LAST_LOGIN
  18. 1,1,Unmi,3,2009-1-5 20:34
  19. 2,2,Fantasia,5,2008-10-15
  20. 3,3,隔叶黄 莺,8,2009-1-2
  21. 4,4,Kypfos,NULL,NULL
  22. 5,5,不知 秋,1,2008-12-23

2) 执行一样的命令:

sqlldr dbuser/dbpass@dbservice control=users.ctl

比 如,在控制台会显示这样的信息:

C:\>sqlldr dbuser/dbpass@dbservice control=users.ctl

SQL*Loader: Release 9.2.0.1.0 - Production on 星期三 1月 7 22:26:25 2009

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

达到提交点,逻辑记录计数4

达到提交点,逻辑记录计数5

上面的控制文 件包含的内容比较复杂(演示目的),请根据注释理解每个参数的意义。还能由此发掘更多用法。

三:最后说下有关 SQL *Loader 的性能与并发操作

1) ROWS 的默认值为 64,你可以根据实际指定更合适的 ROWS 参数来指定每次提交记录数。(体验过在 PL/SQL Developer 中一次执行几条条以上的 insert 语句的情形吗?)

2)常规导入可以通过使用 INSERT语句来导入数据。Direct导入可以跳过数据库的相关逻辑(DIRECT=TRUE),而直接将数据导入到数据文件中,可以提高导入数据的 性能。当然,在很多情况下,不能使用此参数(如果主键重复的话会使索引的状态变成UNUSABLE!)。

3) 通过指定 UNRECOVERABLE选项,可以关闭数据库的日志(是否要 alter table table1 nologging 呢?)。这个选项只能和 direct 一起使用。

4) 对于超大数据文件的导入就要用并发操作了,即同时运行多个导入任务.

sqlldr   userid=/   control=result1.ctl   direct=true   parallel=true   

  sqlldr   userid=/   control=result2.ctl   direct=true   parallel=true   

  sqlldr   userid=/   control=result2.ctl   direct=true   parallel=true

当加载大量数据时(大约超过10GB),最好抑制日志的产生:   

  

  SQL>ALTER   TABLE   RESULTXT   nologging; 

  

  这样不产生REDO LOG,可以提高效率。然后在 CONTROL 文件中 load data 上面加一行:unrecoverable,  此选项必须要与DIRECT共同应用。   

  

  在并发操作时,ORACLE声称可以达到每小时处理100GB数据的能力!其实,估计能到 1-10G 就算不错了,开始可用结构 相同的文件,但只有少量数据,成功后开始加载大量数据,这样可以避免时间的浪费。

(注意:一般只能用ASCII码形式,切记要转换编码,不然导入数据为空)

参考:1. Oracle SQL*Loader  -- 英文,Sql Loader 的官方使用说明,包含多种类型的  Demo

        2. sql loader的用法  -- 列出了 sql loader 的选择参数的中文说明

        3. 使用SQL Loader导入大量数据,避免使用SQL频繁写库 -- 一个简单的例子,快带了解 Sql Loader 的用法

        4. Oracle SQL Loader的详细语法

        5. oracle sql loader全攻略 -- 还算名符其实。并讲了如何用 SQL *Plus 的  spool 或 UTL_FILE 包生成数据文件

        6. SQL*Loader Control File Reference   -- 英文,控制文件使用参考

        7. 学习oracle sql loader 的使用 

        8. 用 sqlloader(sqlldr)装载LOB数据  -- LOB 的内类是一个外部文件,用 sql loader 导入到数据库

        9. SQLLDR直 接加载几个参数的测试

        10.Maximizing SQL*Loader Performance

sqlldr的用法 (这个最完整)的更多相关文章

  1. 关于 Oracle 的数据导入导出及 Sql Loader (sqlldr) 的用法

    在 Oracle 数据库中,我们通常在不同数据库的表间记录进行复制或迁移时会用以下几种方法: 1. A 表的记录导出为一条条分号隔开的 insert 语句,然后执行插入到 B 表中2. 建立数据库间的 ...

  2. sqlldr的用法

    在 Oracle 数据库中,我们通常在不同数据库的表间记录进行复制或迁移时会用以下几种方法: 1. A 表的记录导出为一条条分号隔开的 insert 语句,然后执行插入到 B 表中2. 建立数据库间的 ...

  3. 大规模数据导入和导出(oracle)

    请期待... http://www.cnblogs.com/xwdreamer/archive/2012/06/08/2541678.html Oracle sqlldr的用法 (这个最完整) htt ...

  4. 【Oracle123】向OracleDB导入*.csv文件数据

    SQL*Loader Control File Reference https://docs.oracle.com/cd/B10501_01/server.920/a96652/ch05.htm Or ...

  5. sqlldr 用法

    转自:http://blog.chinaunix.net/uid-23622436-id-2394093.html 在 Oracle 数据库中,我们通常在不同数据库的表间记录进行复制或迁移时会用以下几 ...

  6. java调用sqlldr导入csv文件数据到临时表

    package cn.com.file;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File; ...

  7. oracle sqlloader 用法

    向oracle中导入*.csv文件   1.什么是*.csv,如何得到? 里面存放的是数据表.每行代表数据库表格的一行, 每行中,每两个数据中间由逗号","分割. *.csv可以通 ...

  8. sqlldr的使用

    1,在公司进行预处理的时候,发现文件不能入库,而公司前辈使用的是sqlldr的技术将解析后的文件入库,前辈在测试的时候使用的是本机上的数据库(见图一),没有使用完整的远程连接oracle的正确方式,所 ...

  9. Oracle数据加载之sqlldr工具的介绍

    环境: 服务端:RHEL6.4 + Oracle 11.2.0.4 客户端:WIN10 + Oracle 11.2.0.1 client 目录: sqlldr语法 sqlldr实验准备 sqlldr常 ...

随机推荐

  1. Python traceback的优雅处理

    刚接触Python的时候,简单的异常处理已经可以帮助我们解决大多数问题,但是随着逐渐地深入,我们会发现有很多情况下简单的异常处理已经无法解决问题了,如下代码,单纯的打印异常所能提供的信息会非常有限. ...

  2. python2.7报错Non-ASCII character '\xe5' in file knn.py on line 3, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

    Python默认是以ASCII作为编码方式的,如果在自己的Python源码中包含了中文(或者其他非英语系的语言),此时即使你把自己编写的Python源文件以UTF-8格式保存了,但实际上,这依然是不行 ...

  3. Android 应用防止被二次打包指南

    前言 “Android APP二次打包”则是盗版正规Android APP,破解后植入恶意代码重新打包.不管从性能.用户体验.外观它都跟正规APP一模一样但是背后它确悄悄运行着可怕的程序,它会在不知不 ...

  4. iOS -- Effective Objective-C 阅读笔记 (2)

    1: 多用类型常量, 少用 #define 预处理指令 #define 预处理指令会把碰到的所有 指定名称 一律换位 定义的内容, 这样的话, 假设此指令在某个头文件中, 那么所有引入这个头文件的代码 ...

  5. The word 'localhost' is not correctly spelled 这个问题怎么解决

    The word 'localhost' is not correctly spelled 这个问题怎么解决 有时工程中有下划线并提示 The word is not correctly spelle ...

  6. Confluence 6 重构 ancestor 表

    ancestor 表记录了上级和下级(子页面)页面之间的关系.这个表格同时被用来确定子页面是否具有从上级页面继承来的限制(restrictions)权限. 偶尔 ancestor 表格中的数据可能被损 ...

  7. Confluence 6 用户目录图例 - 可读写连接 LDAP

    上面的图:Confluence 连接到一个 LDAP 目录. https://www.cwiki.us/display/CONFLUENCEWIKI/Diagrams+of+Possible+Conf ...

  8. 第一次Java测试及感触

    周四进行了java测试,感触很深,测试的题目是用Java实现一个ATM机的管理系统.最后3个小时后,我没有完成这次测试,但是我找到了自己的很多不足,明确了自己的问题究竟在哪里. 关于这次测试我不会的最 ...

  9. linux和windows下,C/C++开发的延时函数,sleep函数

    简介: 函数名: sleep   功 能: 执行挂起一段时间   用 法: unsigned sleep(unsigned seconds);   在VC中使用带上头文件   #include < ...

  10. Linux用户、用户组、文件权限学习笔记

    最近打算更仔细学习一下linux操作系统.先是恶补了一下用户.用户组.文件权限这三样比较重要的知识.学习这几样东西,得先掌握linux的权限系统相关知识.linux的权限系统主要是由用户.用户组和权限 ...