Oracle SQL*Loader
来源:互联网 发布:linux 复制目录及文件 编辑:程序博客网 时间:2024/06/06 03:57
-- Start
SQL*Loader 是 Oracle 提供的一个工具用来将文件中的数据导入到一个或多个表中。你可以在 Oracle 的安装目录中找到它 C:\oraclexe\app\oracle\product\11.2.0\server\bin\sqlldr.exe
目前,我们最常用的用来传输数据的文件格式有 2 种,一种是分隔符文件(如:CSV),另一种是定长文件,下面我们通过例子来看看如果导入这两种文件。
首先,我们创建如下的表。
CREATE TABLE EMPLOYEES( EMPLOYEE_ID NUMBER(6,0) NOT NULL, FIRST_NAME VARCHAR2(20) NOT NULL, LAST_NAME VARCHAR2(25) NOT NULL, EMAIL VARCHAR2(50) NULL, HIRE_DATE DATE NULL, SALARY NUMBER(8,2) NULL, UPDATE_DATE_TIME TIMESTAMP NULL);
分隔符文件例子1
假设我们有下面的文件(C:\log\employees.txt)
1,bo,shang,2015-01-01,8888.88,2015-02-19 22:15:00.0002,san,zhang,2015-02-02,9999.99,2015-02-19 22:15:00.000
试一试下面的命令导入文件到 EMPLOYEES 表吧。
sqlldr USERID=DBuser/shangbo -- 指定连接数据库用户名,密码ROWS=1000 -- 每 1000 条提交一次BAD=C:\log\employees.bad -- 保存那些在导入的过程中,由于格式等问题出错的行DISCARD=C:\log\employees.dsc -- 保存那些由于某些条件不满足而丢弃的行LOG=C:\log\employees.log -- 保存日志文件CONTROL=C:\log\employees.ctl -- 控制文件,用来告诉 SQL*Loader 如何导入数据
啊,不好使啊,那是因为你还没有 employees.ctl 控制文件,没有它,SQL*Loader 就不知道如何导入数据,来吧,把下面的内容保存到 employees.ctl 再试一试。
-- 要导入的数据文件LOAD DATA INFILE 'C:\log\employees.txt'-- APPEND 表示将数据添加到表中-- REPLACE 表示先 DELETE 所有数据,然后导入-- TRUNCATE 表示先 TRUNCATE 所有数据,然后导入-- INSERT 只适用于空表,如不是空表会报错APPEND INTO TABLE employeesFIELDS TERMINATED BY ',' -- 表示文件中字段之间使用逗号分隔(EMPLOYEE_ID CHAR, -- 此处的字段名必须和表的列名一致FIRST_NAME , -- 如没有指定数据类型,默认为 CHARLAST_NAME , -- 注意,此处的数据类型是 SQL*Loader 的数据类型,和表的数据类型不一样HIRE_DATE DATE "YYYY-MM-DD", -- 指定 DATE 类型和格式SALARY CHAR, -- SQL*Loader 的 CHAR 类型可以自动转成任何表的数据类型UPDATE_DATE_TIME TIMESTAMP "YYYY-MM-DD HH24:MI:SS.FF3")
上面的控制文件中,我们没有指定 EMAIL 列如何导入,所以它为 NULL。如果你想让某个列是 NULL,不指定它即可。
分隔符文件例子2
有些分隔符文件的字段是用双引号括起来的,还有些字段的前面或后面有空格,如何处理这样的文件呢?
1,"bo","shang","2015-01-01",8888.88,"2015-02-19 20:15:00.000"2,"san","zhang","2015-02-02",9999.99,"2015-02-18 21:15:00.000"3 ,"si" ,"li" ,"2015-03-01" ,6666.66 ,"2015-02-17 22:15:00.000"4, "wu", "wang", "2015-04-02", 7777.77, "2015-02-16 23:15:00.000"
要导入这样的文件,我们只要在控制文件中加入 OPTIONALLY ENCLOSED BY 子句即可。
LOAD DATA INFILE 'C:\log\employees.txt'REPLACE INTO TABLE employeesFIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'(EMPLOYEE_ID ,FIRST_NAME ,LAST_NAME ,HIRE_DATE DATE "YYYY-MM-DD",SALARY ,UPDATE_DATE_TIME TIMESTAMP "YYYY-MM-DD HH24:MI:SS.FF3")
分隔符文件例子3
上面两个文件都是比较完美的,有时候实际的情况是非常复杂的,例如,现在要求你把下面的文件导入到下面的表中。要求
1. 忽略第一行和最后一行
2. EMPLOYEE_ID 由数据库自动生成
3. NAME 由 FIRST_NAME 和 LAST_NAME 组成且要转成大写,如:SHANGBO
4. 忽略 ENGLISH_NAME 列
5. 如果 HIRE_DATE 是空,则插入 NULL
6. 如果 SALARY 是空,则插入 0
7. ENTER_USER 插入默认值 'SYSTEM'
8. ENTER_DATE_TIME 插入当前系统时间
9. 忽略 ACTIVE 是 n 的行
要导入的文件
FIRST_NAME,LAST_NAME,ENGLISH_NAME,HIRE_DATE,SALARY,ACTIVEbo,shang,scott,2015-01-01,8888.88,ysan,zhang,mike,,,ysi ,li ,darren , , ,ywu, wang, eric, 2015-04-02, 7777.77, nEND OF FILE
要导入的表
CREATE TABLE EMPLOYEES(EMPLOYEE_ID NUMBER(6,0) NOT NULL,NAME VARCHAR2(20 BYTE) NOT NULL,HIRE_DATE DATE NULL,SALARY NUMBER(8,2) DEFAULT 0 NOT NULL,ENTER_USER VARCHAR2(20 BYTE) NULL,ENTER_DATE_TIMETIMESTAMP(6) NULL);
控制文件
LOAD DATA INFILE 'C:\log\employees.txt'REPLACE INTO TABLE employeesWHEN (ACTIVE!='n')FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'(EMPLOYEE_ID SEQUENCE(1, 1),FIRST_NAMEBOUNDFILLER, -- BOUNDFILLER 表示该列不保存在表中,但可以用在下面的 EXPRESSION 表达式中LAST_NAMEBOUNDFILLER,NAME EXPRESSION "UPPER(RTRIM(:LAST_NAME) || RTRIM(:FIRST_NAME))", -- EXPRESSION 表示后面是一个SQL表达式ENGLISH_NAME FILLER, -- FILLER 表示该列不保存在表中,它和 BOUNDFILLER 区别是它不能用在 EXPRESSION 表达式中HIRE_DATEDATE "YYYY-MM-DD" NULLIF HIRE_DATE=BLANKS, -- NULLIF 表示如果文件中 HIRE_DATE 是一个或多个空白字符,则插入 NULL 到表中SALARY "NVL(:SALARY, 0)", -- :SALARY 表示引用文件中的 SALARY 列ACTIVE FILLER, -- 忽略此列ENTER_USER CONSTANT 'SYSTEM', -- CONSTANT 表示后面是一个常量ENTER_DATE_TIME EXPRESSION "CURRENT_TIMESTAMP")
导入命令
-- SKIP=1 表示跳过第一条sqlldr USERID=DBuser/shangbo ROWS=1000 BAD=C:\log\employees.bad DISCARD=C:\log\employees.dsc LOG=C:\log\employees.log CONTROL=C:\log\employees.ctl SKIP=1
定长文件例子
现在我们把“分隔符文件例子3”中的文件改成定长文件,看看如何导入定长文件。
要导入的文件
FIRST_NAME LAST_NAME ENGLISH_NAME HIRE_DATE SALARY ACTIVEbo shang scott 2015-01-01 8888.88 y san zhang mike y si li darren y wu wang eric 2015-04-02 7777.77 n END OF FILE
要导入的表
CREATE TABLE EMPLOYEES(EMPLOYEE_ID NUMBER(6,0) NOT NULL,NAME VARCHAR2(20 BYTE) NOT NULL,HIRE_DATE DATE NULL,SALARY NUMBER(8,2) DEFAULT 0 NOT NULL,ENTER_USER VARCHAR2(20 BYTE) NULL,ENTER_DATE_TIMETIMESTAMP(6) NULL);
控制文件
-- fix 表示它是一个定长文件,62表示每行的长度,注意包含换行符哦LOAD DATA INFILE 'C:\log\employees.txt' "fix 62"REPLACE INTO TABLE employeesWHEN (ACTIVE='y')(EMPLOYEE_ID SEQUENCE(1, 1),FIRST_NAME BOUNDFILLER POSITION(1:11), -- 位置从1开始LAST_NAME BOUNDFILLER POSITION(12-21), -- : 和 - 完全相同NAME EXPRESSION "UPPER(:LAST_NAME || :FIRST_NAME)",ENGLISH_NAME FILLER POSITION(*:34), -- * 表示相对上一个位置开始HIRE_DATEPOSITION(*:45) DATE "YYYY-MM-DD" NULLIF HIRE_DATE=BLANKS, SALARY POSITION(*:54) "NVL(:SALARY, 0)",ACTIVE FILLER POSITION(*),ENTER_USER CONSTANT 'SYSTEM',ENTER_DATE_TIME EXPRESSION "CURRENT_TIMESTAMP")
直接路径导入
上面例子的导入方法本质上是构造 INSERT 语句,Oracle 还提供了一种直接路径导入的方法,它是将要导入的文件直接格式化成数据库文件,所以速度会更快。
在使用直接路径导入之前,我们需要运行下面的 SQL 设置一下数据库,这个 SQL 只需要设置一次。
@C:\oraclexe\app\oracle\product\11.2.0\server\rdbms\admin\catldr.sql
然而,有利就有弊,使用直接路径导入我们不能让数据库自动帮我们生成主键,也无法执行 CHECK 和 外键约束,也很容易导致索引不可用。所以,通常我们先删除索引,导入后重建索引,这样可以提高导入效率。那么如何使用直接路径导入呢?很简单,将 DIRECT 参数设置成 true 就可以了,为了进一步提高效率,我们还可以设置 PARALLEL 参数为 true。
下面的命令使用直接路径导入“分隔符文件例子1”的文件
-- DIRECT=true 设置直接路径导入-- PARALLEL=true 使用并行导入sqlldr USERID=DBuser/shangbo DIRECT=true PARALLEL=true ROWS=10000 BAD=C:\log\employees.bad DISCARD=C:\log\employees.dsc LOG=C:\log\employees.log CONTROL=C:\log\employees.ctl
-- 更多参见:Oracle 精萃
-- 声明:转载请注明出处
-- Last edited on 2015-02-21
-- Created by ShangBo on 2015-02-20
-- End
- Oracle SQL*Loader 使用指南
- Oracle sql*loader 使用指南
- oracle sql*loader使用方法
- Oracle SQL*Loader FAQ
- Oracle SQL*Loader 使用指南
- Oracle 的SQL*LOADER
- Oracle SQL Loader
- Oracle SQL Loader 使用说明
- Oracle SQL Loader
- oracle sql loader
- Oracle SQL*Loader 使用指南
- Oracle SQL Loader
- Oracle Sql Loader
- Oracle SQL Loader
- sql loader ---ORACLE SQLLDR
- Oracle SQL Loader
- Oracle SQL*Loader
- oracle sql*loader使用方法
- HDU 5176 The Experience of Love(带权并查集)
- 第三方应用分享到微信朋友圈功能
- LPC2138编程时出现错误“Timer.sct(7): error: L6236E: No section matches selector - no section to be FIRST/LAS
- java软件复杂运算,同时显示进度条的一种方法
- 一款桌面英语翻译软件介绍
- Oracle SQL*Loader
- Linux的ACL权限
- Leetcode:Path Sum 菜鸟解法
- hdoj 1874 通畅工程续 (最短路)
- Java中Runnable和Thread的区别
- 00-自测1. 打印沙漏(20)
- 阿里云cos,memcached无法使用
- oracle使用pagesize命令
- 黑马程序员--对File类的理解