我正在使用Linux shell中的Oracle Sql Loader Utility将csv数据加载到Oracle DB中。 但我注意到,如果源csv文件行结尾是' \ r \ n' (Windows格式),sqlldr无法加载最后一列的数据。
例如,如果最后一列是FLOAT类型(在ctl文件中定义为' FLOAT EXTERNAL'),则sqlldr失败,并且' ORA-01722:无效数字':
Sqlldr ctl文件:
OPTIONS(silent=(HEADER))
load data
replace
into table fp_basic_bd
fields terminated by "|" optionally enclosed by '"'
TRAILING NULLCOLS
(
FS_PERM_SEC_ID CHAR(20),
"DATE" DATE "YYYY-MM-DD",
ADJDATE DATE "YYYY-MM-DD",
CURRENCY CHAR(3),
P_PRICE FLOAT EXTERNAL,
P_PRICE_OPEN FLOAT EXTERNAL,
P_PRICE_HIGH FLOAT EXTERNAL,
P_PRICE_LOW FLOAT EXTERNAL,
P_VOLUME FLOAT EXTERNAL
)
sqlldr执行命令:
sqlldr -userid XXX -data ./test.data -log ./test.log -bad ./test.errors -control test.ctl -errors 3 -skip_unusable_indexes -skip_index_maintenance
sqlldr错误日志:
Column Name Position Len Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
FS_PERM_SEC_ID FIRST 20 | O(") CHARACTER
"DATE" NEXT * | O(") DATE YYYY-MM-DD
ADJDATE NEXT * | O(") DATE YYYY-MM-DD
CURRENCY NEXT 3 | O(") CHARACTER
P_PRICE NEXT * | O(") CHARACTER
P_PRICE_OPEN NEXT * | O(") CHARACTER
P_PRICE_HIGH NEXT * | O(") CHARACTER
P_PRICE_LOW NEXT * | O(") CHARACTER
P_VOLUME NEXT * | O(") CHARACTER
value used for ROWS parameter changed from 300000 to 65534
Record 1: Rejected - Error on table FP_BASIC_BD, column P_VOLUME.
ORA-01722: invalid number
Record 2: Rejected - Error on table FP_BASIC_BD, column P_VOLUME.
ORA-01722: invalid number
当我将Windows行结尾替换为Unix行时,所有错误都消失了,所有数据都正确加载。
我的问题是:如何在sqlldr配置文件中指定行终止符char,但仍然在shell命令中保留源文件名?
我已经看到了一些如何使用流记录格式http://docs.oracle.com/cd/E11882_01/server.112/e16536/ldr_control_file.htm#SUTIL1087执行此操作的示例, 但是这些例子在我的情况下不适用,因为我需要在shell命令中保留数据文件的名称,而不是在ctl文件中。
答案 0 :(得分:3)
我最近在通过csv文件将数据加载到我的表时遇到了同样的问题。 我的文件看起来像这样:
LOAD DATA
infile '/ipoapplication/utl_file/LBR_HE_Mar16.csv'
REPLACE
INTO TABLE LOAN_BALANCE_MASTER_INT
fields terminated by ',' optionally enclosed by '"'
(
ACCOUNT_NO,
CUSTOMER_NAME,
LIMIT,
REGION,
TERM_AGREEMENT INTEGER EXTERNAL
)
正如你所提到的,我一直收到同样的错误'无效号码' 事实证明这通常发生 - 当您的列数据类型为Number但您从csv文件获取的数据是字符串时,因此oracle loader无法执行字符串到数字的转换。 - 当csv文件中的字段被某些分隔符终止时,比如空格,制表符等。
这就是我改变我的ctl文件的方式:
LOAD DATA
infile '/ipoapplication/utl_file/LBR_HE_Mar16.csv'
REPLACE
INTO TABLE LOAN_BALANCE_MASTER_INT
fields terminated by ',' optionally enclosed by '"'
(
ACCOUNT_NO,
CUSTOMER_NAME,
LIMIT,
REGION,
TERM_AGREEMENT INTEGER Terminated by Whitespace
)
答案 1 :(得分:1)
尝试使用stream record format并指定终止符字符串。来自文档
在基于UNIX的平台上,如果未指定terminator_string,则SQL * Loader默认为换行符\ n。
终结符字符串应该允许您指定字符组合。