Oracle SQL sqlldr 未将 latitude/longitude 作为浮点数导入

Oracle SQL sqlldr not importing a latitude/longitude as float

我正在尝试使用 sql*loader 导入一些数据,但无法导入 latitude/longitude。在 table 上,这些列是 FLOAT(126) 并且在数据文件上只是文本。我尝试在 sqlldr 控制文件上使用 FLOAT EXTERNAL,但它不起作用。我收到 ORA-01722: 无效数字。

Describe my_table;

Name                      Null     Type         
------------------------- -------- ------------ 
PRE_ID                    NOT NULL NUMBER(38)   
PRE_DH                    NOT NULL TIMESTAMP(6) 
PRE_PRO                   NOT NULL NUMBER(38)   
PRE_INF                   NOT NULL NUMBER(38)   
PRE_TPL                   NOT NULL NUMBER(38)   
PRE_LAT                   NOT NULL FLOAT(126)   
PRE_LNG                   NOT NULL FLOAT(126)

数据文件:

55831;08/12/2016 16:48:07;1;-128;2;-22.4741249084473;-50.55194854736336
55831;09/12/2016 08:02:06;1;-128;2;-22.5002975463867;-50.8194427490234
55831;09/12/2016 19:12:06;1;-128;2;-22.5002975463867;-50.8194427490234

和sqlldr控制文件:

load data 
infile 'my_file.csv' "str '\r\n'"
append
into table my_table
fields terminated by ';'
trailing nullcols
           ( PRE_ID CHAR(4000),
             PRE_DH TIMESTAMP "DD/MM/YYYY HH24:MI:SS",
             PRE_PRO CHAR(4000),
             PRE_INF CHAR(4000),
             PRE_TPL CHAR(4000),
             PRE_LAT FLOAT EXTERNAL,
             PRE_LNG FLOAT EXTERNAL,
             )

日志文件:

Table MY_TABLE, loaded from every logical record.
Insert option in effect for this table: APPEND
TRAILING NULLCOLS option in effect

   Column Name                  Position   Len  Term Encl Datatype
------------------------------ ---------- ----- ---- ---- ---------------------
PRE_ID                              FIRST  4000   ;       CHARACTER            
PRE_DH                               NEXT     *   ;       DATETIME DD/MM/YYYY HH24:MI:SS
PRE_PRO                              NEXT  4000   ;       CHARACTER            
PRE_INF                              NEXT  4000   ;       CHARACTER            
PRE_TPL                              NEXT  4000   ;       CHARACTER            
PRE_LAT                              NEXT     *   ;       CHARACTER            
PRE_LNG                              NEXT     *   ;       CHARACTER            


value used for ROWS parameter changed from 64 to 1
Record 1: Rejected - Error on table MY_TABLE, column PRE_LAT.
ORA-01722: invalid number

Record 2: Rejected - Error on table MY_TABLE, column PRE_LAT.
ORA-01722: invalid number

Record 3: Rejected - Error on table MY_TABLE, column PRE_LAT.
ORA-01722: invalid number

您看到这一点是因为操作系统环境的设置方式导致 Oracle 将逗号视为小数分隔符,将句点视为组分隔符。有趣的是,您的错误消息是英文的,所以不确定您设置的确切内容,但您可以看到类似 NLS_LANG="FRENCH_FRANCE.WE8ISO8859P1".

的内容

从日志中您可以看到 CSV 文件中的字段被读取为字符数据。目标列是一个浮点数(任何类型的数字列都会有同样的问题),这意味着隐式转换正在发生,并且正在使用您的 NLS 设置。你可以更简单地看到同样的事情:

alter session set NLS_NUMERIC_CHARACTERS='.,';
select to_number('-22.4741249084473') from dual;

TO_NUMBER('-22.4741249084473')
------------------------------
             -22.4741249084473

alter session set NLS_NUMERIC_CHARACTERS=',.';
select to_number('-22.4741249084473') from dual;

Error report -
ORA-01722: invalid number

相同的转换,但 alter session 交换了逗号和句点的含义。

您可以通过 NLS_LANG:

将您的环境明确设置为具有正确 NLS 数字字符的环境
export NLS_LANG="ENGLISH_UNITED KINGDOM.WE8ISO8859P1"

或者只是那个特定的设置:

export NLS_NUMERIC_CHARACTERS='.,'

... 在 运行 SQL*Loader.

之前