Oracle SQL sqlldr不将纬度/经度导入为float

时间:2017-01-06 15:19:09

标签: oracle sql-loader

我正在尝试使用sql * loader导入一些数据,但我无法导入纬度/经度。在表上,这些列是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

1 个答案:

答案 0 :(得分:2)

您看到这一点是因为操作系统环境的设置方式导致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之前。