在Linux环境下SQLLOADER导入LOB数据,碰到了这个错误。
奇怪的是,整个测试在Windows环境下测试没有问题,包括控制文件和数据文件,都是直接拷贝到Linux环境中,唯一的修改是针对Windows和Linux路径的区别,对数据文件中的路径进行了修改。
控制文件如下:
[oracle@dbserver1 sqlldr]$ more sqlldr_1M.ctl
LOAD DATA
INFILE 'filename.dat'
INTO TABLE T_LOAD_1M
TRUNCATE
FIELDS TERMINATED BY ','
(ID CHAR(255),
FULL_NAME CHAR(255),
CREATE_DATE SYSDATE,
CONTENTS LOBFILE(FULL_NAME) TERMINATED BY EOF)
而数据文件filename.dat的格式如下:
[oracle@dbserver1 sqlldr]$ more filename.dat
1,/home/oracle/2M/IMG_5015.JPG
2,/home/oracle/2M/IMG_5016.JPG
3,/home/oracle/2M/IMG_5017.JPG
4,/home/oracle/2M/IMG_5018.JPG
5,/home/oracle/2M/IMG_5022.JPG
6,/home/oracle/2M/IMG_5023.JPG
7,/home/oracle/2M/IMG_5025.JPG
8,/home/oracle/2M/IMG_5026.JPG
9,/home/oracle/2M/IMG_5027.JPG
10,/home/oracle/2M/IMG_5028.JPG
11,/home/oracle/2M/IMG_5029.JPG
12,/home/oracle/2M/IMG_5030.JPG
13,/home/oracle/2M/IMG_5031.JPG
.
.
.
661,/home/oracle/2M/DSC00140.JPG
662,/home/oracle/2M/DSC00141.JPG
663,/home/oracle/2M/DSC00142.JPG
664,/home/oracle/2M/DSC00143.JPG
导入命令很简单,除了制定用户名、密码外,唯一的参数就是控制文件名。结果导出碰到下面的错误。
[oracle@dbserver1 sqlldr]$ sqlldr enmotest/password control=sqlldr_1M.ctl
SQL*Loader: Release 11.2.0.2.0 - Production on Fri Aug 5 15:19:20 2011
Copyright (c) 1982, 2009, Oracle and/or its affiliates. All rights reserved.
' for field CONTENTS table T_LOAD_1Mfile 'IMG_9651.txt
SQL*Loader-553: file not found
SQL*Loader-509: System error: No such file or directory
Commit point reached - logical record count 1
错误指出文件不存在,而第一行的信息比较奇怪,要说没有意义,里面还是包含了有价值的信息的,要说有意义,整个语句没有开头也没有结尾,而且通顺不起来。
由于在Windows环境下测试过,怀疑是Linux环境的bug,检查metalink,找到一个Bug 11777231的描述,虽然和我的问题并不一样,但是这个错误的错误信息帮我找到了方向:
SQL*Loader-502: unable to open data file 'ADFFNTEIICDEV3ADAOAT1.DAT' for
field NOTE_DETAILS_BODY table DLO_STAGE.ADFFNTE
SQL*Loader-553: file not found
SQL*Loader-509: System error: The system cannot find the file specified.
对比这个错误信息和前面的得到的错误信息,可以确定第一行模糊不清的错误肯定是SQL*LOADER-502错误,而导致错误信息不全的原因是由于Linux上的回车没有换行,导致新一行的数据从本行开头覆盖了第一行的信息。
根据行中出现换行的位置,以及找不到文件的错误信息,很容易判断,问题出在数据文件中。而导致文件的原因也就明确了,虽然filename.dat是一个文本文件,但是由于这个dat后缀,在ftp的时候被工具当做了二进制文件,因此没有做转化,而Windows上只有一个回车是正常的,但是Linux上只有回车没有换行就会导致这样的问题。
最简单的办法就是修改数据文件的后缀,然后利用ftp的ASCII码方式或sftp直接拷贝。随后sqlldr导入就没有任何问题了。