本节所讲的列不一致的数据加载有2种情况:一种是数据文件的列数目少于目标表的定义列数目,另外一种就是数据文件的列数目多于目标表的定义列数目。
1.数据文件的列数目少于目标表的定义列数目
在10.2.1节中,我们讲到,当数据文件中某一些行的某些个字段出现没有数据的情况,则在控制文件中使用TRAILING NULLCOLS,规定加载时赋予空值。但是如果遇到整个数据文件中某些列都没有值,也就是前面第一种情况,也可以采用另外一种方法来解决问题。
数据文件test04.dat如下:
31 data
32 clicl
33 wang
34 sing
对应该数据文件的控制文件test04.ctl如下:
LOAD DATA
INFILE test04.dat
DISCARDFILE 'test04.dsc'
APPEND
INTO TABLE LOADTEST
(LOADID POSITION(1:2), OPERNAME POSITION(4:8),OPERTYPE CONSTANT "insert")
运行SQL*Loader,加载数据,
[oracle@nn ~]$ sqlldr nn/123 control=/home/oracle/test04.ctl
查询一下loadtest表,可见数据文件中的4条记录都成功加载了:
除了这种采用CONSTANT参数指定某列值为一个常数之外,也可以使用Oracle本身的函数来指定某列值,比如上面例子中OPERTYPE列值用concat函数来指定,如下:
LOAD DATA
INFILE test04.dat
DISCARDFILE 'test04.dsc'
APPEND
INTO TABLE LOADTEST
(LOADID POSITION(1:2),
OPERNAME POSITION(4:8),
OPERTYPE "concat(:OPERNAME,'insert')")
运行SQL*Loader,加载数据:
查询一下loadtest表,可见数据文件中的4条记录都成功加载了:
2.数据文件的列数目多于目标表的定义列数目
数据文件的列数目多于要加载目标表的列数目,这就意味着数据文件有部分列的数据不需要导入到目标表中,对于数据量少的情况,可以通过直接删除多余的列数据来解决该问题,但是如果对于数据量特别多的情况,就需要在控制文件中使用FILLER关键字来解决这个问题,FILLER用来指定过滤指定的列。
对于定长字符串,直接用POSITION参数就可以限定要加载的列,如上面的例子所示。但是对于有分隔符的不定长格式数据文件,就必须使用FILLER来过滤多余的列数据。下面就举例来演示这个加载过程。
数据文件test05.dat如下:
41,data,update
42,clicl,insert
43,wang,replace
44,sing,insert
但是本案例中不想导入OPERNAME列的数据,此时必须使用FILLER关键字将该列的数据过滤掉,对应该数据文件的控制文件test05.ctl如下:
LOAD DATA
INFILE test05.dat
DISCARDFILE 'test05.dsc'
APPEND
INTO TABLE LOADTEST
FIELDS TERMINATED BY","
(LOADID, OPERNAME FILLER,OPERTYPE )
运行SQL*Loader,加载数据,
[oracle@nn ~]$ sqlldr nn/123 control=/home/oracle/test05.ctl
查询一下loadtest表,可见数据文件中的第2列数据没有被加载进去,其他数据都按要求加载成功: