用SQLLDR来装载CLOB/BLOB列的控制文件例子

本文详细介绍了如何使用 Oracle 的 SQLLDR 工具进行数据装载,特别是针对含有 CLOB 和 BLOB 列的数据表。文章提供了具体的控制文件配置示例,并解决了常见错误,如数据字段超出最大长度的问题。

Oracle的SQLLDR是用来将文本文件中的记录装载到数据库中的工具, 其并行(Parallel),直接(Direct)的装载模式是目前所知最快的方式. 不过用于指定文本格式的控制文件有点难于写, 我在写时也经常需要查阅文档. 为了方便我还是在这儿写一个例子吧, 下面是样表的结构:

SQL> create table test(
2 num_col number(10),
3 char_col char(10),
4 var_col varchar2(10),
5 date_col date,
6 blob_col blob,
7 clob_col clob,
8 raw_col raw(20)
9 );

Table Created.

在这个例子中有CLOB/BLOB列, 因此直接模式不能用, 还需要将ROWS参数设为1, 下面是SQLLDR用的控制文件:

--
-- Generated by AUL/MyDUL, for table hr.test
--
OPTIONS(DIRECT=TRUE,READSIZE=4194304,ERRORS=-1,SKIP=1,ROWS=50000)
LOAD DATA
INFILE 'hr_test.txt' "STR X'0d0a'"
INTO TABLE TEST
FIELDS TERMINATED BY X'7c' TRAILING NULLCOLS 
(
NUM_COL CHAR ,
CHAR_COL CHAR(10) ,
VAR_COL CHAR(10) ,
DATE_COL DATE "YYYY-MM-DD HH24:MI:SS" ,
LOBF_00005 FILLER CHAR(32),
BLOB_COL LOBFILE(LOBF_00005) TERMINATED BY EOF ,
LOBF_00006 FILLER CHAR(32),
CLOB_COL LOBFILE(LOBF_00006) TERMINATED BY EOF ,
RAW_COL CHAR 
)

当然我给的参数肯定不是最好的, 请你试了后告诉我.

当使用sqlldr加载很长的字符串(超过4000)到表中的clob类型中时,老是报错: 数据文件的字段超出最大长度.查找相关资料后得知,sqlldr每次读入文件中数据流的数据类型默认为CHAR ,长度为 255 .所以只要超过255字符的段都会报这个错.解决方法很简单,在控制文件中字段后添加上char(1000000),例如:

LOAD DATA 
INFILE * 
INTO TABLE DEMO 
TRUNCATE 
FIELDS TERMINATED BY ',' 
(d1 ,
d2 char(1000000)
)

其中表demo的列d2是clob类型,当然1000000只是随便用的一个大数字,只要保证加载的长度不超这个数字就成.

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

首先建立表:

SQL> desc lobdemo
名称                                      是否为空? 类型
----------------------------------------- -------- ------------

AA01                                      NOT NULL VARCHAR2(10)
AA02                                      NOT NULL BLOB

以下是ctl控制文件得写法:文件名为ctldemo.ctl

load data
infile 'dump002.dat'
insert
into table "BTGL"."LOBDEMO1" 
FIELDS TERMINATED BY '|' TRAILING NULLCOLS    
("AA01"                             CHAR(3) enclosed by '|',
LOBFILE_COL1                       FILLER CHAR                     ,
"AA02"                             LOBFILE(LOBFILE_COL1) TERMINATED BY EOF NULLIF LOBFILE_COL1 = 'NONE')

然后在DOS下执行:
sqlldr username/password control=ctldemo.ctl

当时要导入得是100多万条,所以我采用了direct方式
c:\>sqlldr username/password control=ctldemo.ctl direct=y

sqlldr也支持多字符分隔符文件导入。只要类似fields terminated by "|||"这样就可以了! 其中|||就是分割符


SQL> create table test(
2 num_col number(10),
3 char_col char(10),
4 var_col varchar2(10),
5 date_col date,
6 blob_col blob,
7 clob_col clob,
8 raw_col raw(20)
9 );

Table Created.

在这个例子中有CLOB/BLOB列, 因此直接模式不能用, 还需要将ROWS参数设为1, 下面是SQLLDR用的控制文件:

--
-- Generated by AUL/MyDUL, for table hr.test
--
OPTIONS(DIRECT=TRUE,READSIZE=4194304,ERRORS=-1,SKIP=1,ROWS=50000)
LOAD DATA
INFILE 'hr_test.txt' "STR X'0d0a'"
INTO TABLE TEST
FIELDS TERMINATED BY X'7c' TRAILING NULLCOLS 
(
NUM_COL CHAR ,
CHAR_COL CHAR(10) ,
VAR_COL CHAR(10) ,
DATE_COL DATE "YYYY-MM-DD HH24:MI:SS" ,
LOBF_00005 FILLER CHAR(32),
BLOB_COL LOBFILE(LOBF_00005) TERMINATED BY EOF ,
LOBF_00006 FILLER CHAR(32),
CLOB_COL LOBFILE(LOBF_00006) TERMINATED BY EOF ,
RAW_COL CHAR 
)

当然我给的参数肯定不是最好的, 请你试了后告诉我.

当使用sqlldr加载很长的字符串(超过4000)到表中的clob类型中时,老是报错: 数据文件的字段超出最大长度.查找相关资料后得知,sqlldr每次读入文件中数据流的数据类型默认为CHAR ,长度为 255 .所以只要超过255字符的段都会报这个错.解决方法很简单,在控制文件中字段后添加上char(1000000),例如:

LOAD DATA 
INFILE * 
INTO TABLE DEMO 
TRUNCATE 
FIELDS TERMINATED BY ',' 
(d1 ,
d2 char(1000000)
)

其中表demo的列d2是clob类型,当然1000000只是随便用的一个大数字,只要保证加载的长度不超这个数字就成.

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

首先建立表:

SQL> desc lobdemo
名称                                      是否为空? 类型
----------------------------------------- -------- ------------

AA01                                      NOT NULL VARCHAR2(10)
AA02                                      NOT NULL BLOB

以下是ctl控制文件得写法:文件名为ctldemo.ctl

load data
infile 'dump002.dat'
insert
into table "BTGL"."LOBDEMO1" 
FIELDS TERMINATED BY '|' TRAILING NULLCOLS    
("AA01"                             CHAR(3) enclosed by '|',
LOBFILE_COL1                       FILLER CHAR                     ,
"AA02"                             LOBFILE(LOBFILE_COL1) TERMINATED BY EOF NULLIF LOBFILE_COL1 = 'NONE')

然后在DOS下执行:
sqlldr username/password control=ctldemo.ctl

当时要导入得是100多万条,所以我采用了direct方式
c:\>sqlldr username/password control=ctldemo.ctl direct=y

sqlldr也支持多字符分隔符文件导入。只要类似fields terminated by "|||"这样就可以了! 其中|||就是分割符

<think>我们正在回答用户关于SQL*Loader控制文件示例的问题。根据引用内容,我们可以知道: 引用[1]提到一个自动生成控制文件的脚本,它根据数据库中的表结构生成控制文件。 引用[2]提到在控制文件中使用EXTERNAL_TABLE=EXECUTE和SEQUENCE参数的情况。 引用[3]提到文件格式和记录终止符。 引用[4]是一个插入语句的示例,但并不是控制文件的内容。 用户想要的是控制文件的使用示例。因此,我们将提供一个基本的控制文件示例,并解释其中的关键部分。 控制文件(通常以.ctl为扩展名)是一个文本文件,用于描述数据文件的结构以及如何将数据加载到数据库表中。 以下是一个简单的控制文件示例,用于将数据加载到一个名为“employees”的表中: 假设表结构为: CREATE TABLE employees ( id NUMBER, name VARCHAR2(100), hire_date DATE, salary NUMBER ); 数据文件(例如:data.txt)内容可能是: 1001,John Smith,2020-01-15,50000 1002,Jane Doe,2019-05-23,60000 控制文件(如:employees.ctl)内容如下: ```sql OPTIONS (SKIP=1) -- 跳过数据文件的第一行(如果有标题行) LOAD DATA INFILE 'data.txt' -- 数据文件路径 BADFILE 'employees.bad' -- 错误数据记录文件 DISCARDFILE 'employees.dsc' -- 不符合条件的数据记录文件 APPEND INTO TABLE employees FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' -- 字段以逗号分隔,可选地被双引号包围 TRAILING NULLCOLS -- 允许末尾的为空 ( id, name, hire_date DATE "YYYY-MM-DD", -- 指定日期格式 salary ) ``` 解释: - `OPTIONS (SKIP=1)`: 跳过数据文件的第一行(通常用于跳过标题行)。 - `LOAD DATA`: 表示开始数据加载的描述。 - `INFILE`: 指定数据文件的位置。 - `BADFILE`: 指定存储加载过程中遇到错误记录的文件。 - `DISCARDFILE`: 指定存储不符合加载条件(如WHEN子句)的记录的文件。 - `APPEND`: 表示向表中追加数据(如果表中有数据,则追加)。其他选项还有`INSERT`(空表插入)、`REPLACE`(删除表中所有记录后插入)和`TRUNCATE`(使用truncate表后插入)。 - `INTO TABLE employees`: 指定目标表。 - `FIELDS TERMINATED BY ','`: 指定字段分隔符为逗号。`OPTIONALLY ENCLOSED BY '"'`表示字段可以被双引号包围(如果数据中有逗号,则可以用双引号将字段括起来)。 - `TRAILING NULLCOLS`: 告诉SQL*Loader将数据中缺少的视为NULL(特别是当数据行末尾的缺失时)。 - 在括号内,我们出了表中的,并可以指定数据类型和格式。例如,这里我们为日期字段指定了格式。 另外,如果数据文件中的字段顺序与表结构不同,可以在括号内调整顺序并指定名,例如: (id, name, hire_date DATE "YYYY-MM-DD", salary) 如果数据文件中的字段顺序与表结构一致,则可以省略名,但为了清晰,建议写上。 运行SQL*Loader命令: sqlldr userid=username/password@database control=employees.ctl log=employees.log 以上是一个基本的示例。根据引用[2],如果我们需要使用序来生成主键,可以在控制文件中使用SEQUENCE函数。例如,假设表的主键id需要从序生成,我们可以这样写: ```sql LOAD DATA INFILE 'data.txt' APPEND INTO TABLE employees FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' TRAILING NULLCOLS ( id SEQUENCE(MAX,1), -- 使用序,从当前最大值+1开始 name, hire_date DATE "YYYY-MM-DD", salary ) ``` 注意:使用序时,需要确保表已经存在,并且序的起始值设置正确。也可以使用数据库序,如引用[2]中提到的,但需要额外的配置。 另外,根据引用[3],记录终止符可以是操作系统相关的(如UNIX的\n,Windows的\r\n),SQL*Loader通常能自动识别。如果记录终止符特殊,可以在控制文件中用`RECORD DELIMITED BY`指定。 我们还可以在控制文件中使用WHEN子句来有条件地加载数据,例如: WHEN (1:5) = 'EMP' -- 只加载前5个字符为'EMP'的记录 以上是一个简单的控制文件示例和解释。用户可以根据实际需求调整。 根据用户要求,生成相关问题:</think>### SQL*Loader 控制文件使用示例 SQL*Loader 控制文件(.ctl)是指导数据加载的核心配置文件,以下是详细示例和说明: #### 基础控制文件示例 ```sql LOAD DATA INFILE 'employees.csv' -- 数据源文件 BADFILE 'employees.bad' -- 错误记录文件 DISCARDFILE 'employees.dsc' -- 丢弃记录文件 APPEND INTO TABLE employees -- 目标表及加载模式 FIELDS TERMINATED BY ',' -- 字段分隔符 OPTIONALLY ENCLOSED BY '"' -- 可选引号包围 TRAILING NULLCOLS -- 允许末尾空 ( emp_id, name, hire_date DATE "YYYY-MM-DD", -- 日期格式转换 salary, dept_id SEQUENCE(MAX,1) -- 自增序 ) ``` **参数说明**: - `INFILE`:数据文件路径(支持多文件) - `APPEND`:数据加载模式(其他选项:`INSERT`/`REPLACE`/`TRUNCATE`) - `FIELDS TERMINATED BY`:字段分隔符(如`,`、`|`等) - `TRAILING NULLCOLS`:处理数据行末尾缺失 - `SEQUENCE`:自动生成序值(替代数据库序)[^2] #### 日期/特殊格式处理 ```sql ( birth_date DATE "DD-MON-YYYY", resume LOBFILE (resume_file) TERMINATED BY EOF -- 加载CLOB文件 ) ``` #### 高级功能示例 1. **条件加载**: ```sql WHEN dept_id != '0' -- 仅加载非零部门 ``` 2. **多表加载**: ```sql INTO TABLE emp WHEN rec_type='EMP' INTO TABLE dept WHEN rec_type='DEPT' ``` 3. **外部表执行**(需配合`EXTERNAL_TABLE=EXECUTE`参数)[^2]: ```sql OPTIONS (EXTERNAL_TABLE=EXECUTE) ``` #### 运行命令 ```bash sqlldr userid=scott/tiger@db control=load.ctl log=load.log ``` ### 常见问题解决 1. **数据截断**:添加`TRUNCATE`或`REPLACE`模式 2. **字符集问题**:在控制文件首行添加 `CHARACTERSET UTF8` 3. **记录终止符**:使用 `RECORD DELIMITED BY '\r\n'` 处理Windows文件[^3] > 自动生成控制文件的脚本可参考[^1],通过数据库表结构自动创建对应控制文件
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值