Oracle Sql Loader“;ORA-01722:无效编号“;加载带有Windows行结尾的CSV文件时
我正在使用Linux shell中的Oracle Sql Loader实用程序将csv数据加载到Oracle DB中。 但我注意到,如果源csv文件的行尾是'\r\n'(Windows格式),sqlldr将无法加载最后一列的数据 例如,如果最后一列是FLOAT类型(在ctl文件中定义为“FLOAT EXTERNAL”),sqlldr将失败,并显示“ORA-01722:无效数字”: Sqlldr ctl文件:Oracle Sql Loader“;ORA-01722:无效编号“;加载带有Windows行结尾的CSV文件时,oracle,sql-loader,Oracle,Sql Loader,我正在使用Linux shell中的Oracle Sql Loader实用程序将csv数据加载到Oracle DB中。 但我注意到,如果源csv文件的行尾是'\r\n'(Windows格式),sqlldr将无法加载最后一列的数据 例如,如果最后一列是FLOAT类型(在ctl文件中定义为“FLOAT EXTERNAL”),sqlldr将失败,并显示“ORA-01722:无效数字”: Sqlldr ctl文件: OPTIONS(silent=(HEADER)) load data replace
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命令中
我看过一些关于如何使用流记录格式的示例,
但这些示例不适用于我的情况,因为我需要在shell命令中保留数据文件的名称,而不是在ctl文件中。尝试使用并指定终止符字符串。从文件中
在基于UNIX的平台上,如果未指定终止符\u字符串,则SQL*加载器默认为换行符,\n
终止符字符串应该允许您指定字符的组合。我最近在通过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
)
正如你提到的,我一直收到相同的错误“无效号码”
事实证明,这种情况经常发生
-当列数据类型为数字,但从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
)
使用
dos2unix-urfilename-urfilename
进行到unix的下线转换,然后sqlldr
应该可以工作?是的,这是我目前处理这个问题的方式。但源数据量太大(每天高达40GB),我正在尝试尽快加载数据。因此,我正在寻找方法,使它只通过sqlldr,而不需要额外的预编辑输入CSV文件。流记录格式迫使开发人员将输入文件名保存在ctl文件中。这不是我真正需要的解决方案,我需要将输入文件名保留在shell命令中(请参阅我的问题)。您的修复工作正常,但我们必须使用“TERM_AGREEMENT INTEGER外部以空格终止”