2013年(350)
分类: Oracle
2013-04-10 11:25:13
提出这样的问题,说明你没有认真看我们前面的示例,对,前面你睡着了,OK,那就清醒一下,重新查看一下表结构:
SQL> DESC BONUS;
名称 是否为空? 类型
---------------- -------- ----------------------------
ENAME VARCHAR2(10)
JOB VARCHAR2(9)
SAL NUMBER
COMM NUMBER之前的诸多演示,正是在数据文件中列比表中列要少的环境下创建的,这说明列少不怕,关键是看控制文件中的配置。考虑下面一种情况,如果缺少的列必须赋值又怎么办呢?没有关系,稍改下控制文件即可,直接指定COMM列,并赋初始值0(这里仍然引用ldr_case3.dat中的数据):
LOAD DATA
INFILE ldr_case3.dat
TRUNCATE INTO TABLE BONUS
(
ENAME position(1:5),
JOB position(7:15),
SAL position(17:20),
COMM "0"
)示例保存为控制文件ldr_case4.ctl。
执行SQLLDR命令:
F:\oracle\script>SQLLDR SCOTT/TIGER CONTROL=LDR_CASE4.CTL
SQL*Loader: Release 10.2.0.1.0 - Production on 星期三 3月 11 17:01:01 2009
Copyright (c) 1982, 2007, Oracle. All rights reserved.
达到提交点 - 逻辑记录计数 3
达到提交点 - 逻辑记录计数 4SQL*Plus中查看导入结果:
SQL> SELECT * FROM BONUS;
ENAME JOB SAL COMM
---------- ---------- ---------- -----------
SMITH CLEAK 3904 0
ALLEN SALESMAN 2891 0
WARD SALESMAN 3128 0
KING PRESIDENT 2523 0可以再玩儿点更有难度的,根据SAL的值设置COMM列的值,修改控制文件如下:
LOAD DATA
INFILE ldr_case3.dat
TRUNCATE INTO TABLE BONUS
(
ENAME position(1:5),
JOB position(7:15),
SAL position(17:20),
COMM "substr(:SAL,1,1)"
)示例代码保存为控制文件ldr_case5.ctl。
执行SQLLDR命令:
F:\oracle\SCRIPT>SQLLDR SCOTT/TIGER CONTROL=LDR_CASE5.CTL
SQL*Loader: Release 10.2.0.1.0 - Production on 星期三 3月 11 17:13:59 2009
Copyright (c) 1982, 2007, Oracle. All rights reserved.
达到提交点 - 逻辑记录计数 3
达到提交点 - 逻辑记录计数 4SQL*Plus中查看导入结果:
SQL> SELECT * FROM BONUS;
ENAME JOB SAL COMM
---------- -------------------- ---------- ----------
SMITH CLEAK 3904 3
ALLEN SALESMAN 2891 2
WARD SALESMAN 3128 3
KING PRESIDENT 2523 2这里COMM列的值根据SAL列值而定,我们通过一个中的函数substr取SAL值的第一列,赋予COMM列,当然这只是一个示例,DBA可以根据实际需求进行适当的修改,通过SQL中的函数可以实现很多很有意思的转换,也许能够为你省下很大力气,而且如果现有函数无法实现,甚至可以通过PL/SQL编写自定义的函数,然后在SQLLDR的控制文件中调用,调用方式与系统自带函数方式完全相同,这样就可以根据需求对要加载的列做更灵活的处理。
如果数据文件中的列比要导入的表中的列少,处理的时候可能麻烦些,多了反倒更简单,针对不同情况,一般有以下两种处理方式:
方式一:修改数据文件,将多余的数据删除,不过以这种方式处理,小数据量时还算可行,一旦数据文件较大,几百兆甚至上千兆,修改数据文件耗时耗力,这时我们就需要Plan B。
方式二:比如,数据文件如下(同样是基于只做演示的目的,这里三思就不真的提供几百兆甚至上千兆的数据了,不然出版社非把我活吞了不可):
SMITH 7369 CLERK 800 20
ALLEN 7499 SALESMAN 1600 30
WARD 7521 SALESMAN 1250 30
JONES 7566 MANAGER 2975 20
MARTIN 7654 SALESMAN 1250 30
BLAKE 7698 MANAGER 2850 30
CLARK 7782 MANAGER 2450 10
KING 7839 PRESIDENT 5000 10
TURNER 7844 SALESMAN 1500 30
JAMES 7900 CLERK 950 30
FORD 7902 ANALYST 3000 20
MILLER 7934 CLERK 1300 10示例代码保存为数据文件ldr_case6.dat。
我们希望导入第1、3、4列而跳过2、5两列(注意这里指的不是字符列),创建控制文件如下:
LOAD DATA
INFILE ldr_case6.dat
TRUNCATE INTO TABLE BONUS
(
ENAME position(1:6),
TCOL FILLER position(8:11),
JOB position(13:21),
SAL position(23:26)
)示例代码保存为控制文件ldr_case6.ctl。
SQLLDR的控制文件中对列定义时支持FILLER关键字,可以用来指定过滤列,在上述控制文件中,我们就使用该关键字来过滤列,相当于第8到第11列之间的数据不导入。
事实上由于此处为定长字串,我们在控制文件中指定的position参数,已经限定了读取的内容,你甚至可以删除控制文件中TCOL FILLER position(8:11)那行。
执行SQLLDR命令:
F:\oracle\script>SQLLDR SCOTT/TIGER CONTROL=LDR_CASE6.CTL
SQL*Loader: Release 10.2.0.1.0 - Production on 星期三 3月 11 23:13:33 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
达到提交点 - 逻辑记录计数 11
达到提交点 - 逻辑记录计数 12SQL*Plus中查看导入结果:
SQL> SELECT * FROM BONUS;
ENAME JOB SAL COMM
---------- --------- --------- ----------
SMITH CLERK 800
ALLEN SALESMAN 1600
WARD SALESMAN 1250
JONES MANAGER 2975
MARTIN SALESMAN 1250
BLAKE MANAGER 2850
CLARK MANAGER 2450
KING PRESIDENT 5000
TURNER SALESMAN 1500
JAMES CLERK 950
FORD ANALYST 3000
MILLER CLERK 1300结果符合要求,不过,如果数据文件中字符串不是定长格式,而是通过分隔符来处理的,那控制文件中就需要注意,如数据文件如下:
SMITH,7369,CLERK,800,20
ALLEN,7499,SALESMAN,1600,30
WARD,7521,SALESMAN,1250,30
JONES,7566,MANAGER,2975,20
MARTIN,7654,SALESMAN,1250,30
BLAKE,7698,MANAGER,2850,30
CLARK,7782,MANAGER,2450,10
KING,7839,PRESIDENT,5000,10
TURNER,7844,SALESMAN,1500,30
JAMES,7900,CLERK,950,30
FORD,7902,ANALYST,3000,20
MILLER,7934,CLERK,1300,10示例代码保存为数据文件ldr_case7.dat。
创建控制文件,此时控制文件中必须指定FILLER,不然列值就有可能不对应。例如,创建控制文件如下:
LOAD DATA
INFILE ldr_case7.dat
TRUNCATE INTO TABLE BONUS
FIELDS TERMINATED BY ","
(ENAME,TCOL FILLER,JOB,SAL)
示例代码保存为控制文件ldr_case7.ctl。执行SQLLDR命令:
F:\oracle\script>SQLLDR SCOTT/TIGER CONTROL=LDR_CASE7.CTL
SQL*Loader: Release 10.2.0.1.0 - Production on 星期三 3月 11 23:27:21 2009
Copyright (c) 1982, 2005, Oracle. All rights reserved.
达到提交点 - 逻辑记录计数 11
达到提交点 - 逻辑记录计数 12SQL*Plus中查看导入结果:
SQL> SELECT * FROM BONUS;
ENAME JOB SAL COMM
---------- --------- --------- ----------
SMITH CLERK 800
ALLEN SALESMAN 1600
WARD SALESMAN 1250
JONES MANAGER 2975
MARTIN SALESMAN 1250
BLAKE MANAGER 2850
CLARK MANAGER 2450
KING PRESIDENT 5000
TURNER SALESMAN 1500
JAMES CLERK 950
FORD ANALYST 3000
MILLER CLERK 1300竣工~~~
=================================================
全书目录:http://space.itpub.net/7607759/viewspace-622699
样书预览:http://space.itpub.net/7607759/viewspace-622515
马上购买: