加载带有Windows行结尾的CSV文件时,Oracle Sql Loader"ORA-01722:无效编号"

dan*_*yar 7 oracle sql-loader

我正在使用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
 )
Run Code Online (Sandbox Code Playgroud)

sqlldr执行命令:

sqlldr -userid XXX -data ./test.data -log ./test.log -bad ./test.errors -control test.ctl -errors 3 -skip_unusable_indexes -skip_index_maintenance
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

当我将Windows行结尾替换为Unix行时,所有错误都消失了,所有数据都正确加载.

我的问题是:如何在sqlldr配置文件中指定行终止符char,但仍然在shell命令中保留源文件名?

我已经看到了一些如何使用流记录格式的例子http://docs.oracle.com/cd/E11882_01/server.112/e16536/ldr_control_file.htm#SUTIL1087,但这些例子不适用于我的情况因为我需要在shell命令中保留数据文件的名称,而不是在ctl文件中.

arj*_*aur 6

我最近在通过 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
    )
Run Code Online (Sandbox Code Playgroud)

正如您所提到的,我一直收到相同的错误“无效数字”结果证明这通常会发生 - 当您的列数据类型为 Number 但您从 csv 文件中获取的数据为字符串时,因此 oracle 加载程序无法执行字符串到数字。- 当 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
    )
Run Code Online (Sandbox Code Playgroud)

  • 您的修复有效,但我们必须使用“TERM_AGREEMENT INTEGER EXTERNAL Terminated by Whitespace (3认同)

Mar*_*ner 1

尝试使用流记录格式并指定终止符字符串。来自文档

在基于 UNIX 的平台上,如果未指定 terminator_string,SQL*Loader 默认为换行符 \n。

终止符字符串应该允许您指定字符的组合。