【问题标题】:Oracle SQL sqlldr not importing a latitude/longitude as floatOracle SQL sqlldr 未将纬度/经度导入为浮点数
【发布时间】:2017-01-06 15:19:09
【问题描述】:

我正在尝试使用 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

【问题讨论】:

  • 也许是一个愚蠢的问题(我的问题,如下):为什么不能简单地将 PRE_LAT 和 PRE_LNG 声明为标准 Oracle 数据类型 NUMBER?当然,您不必关心纬度或经度中的小数位数。
  • 你的意思是改变表上的数据类型?不能那样做。不是我的表,不是我的数据库。 :-/
  • 是的,我就是这个意思。太糟糕了。除此之外我无能为力,我自己没有使用过 sqlldr。祝你好运!
  • 您的 NLS_LANG 环境变量设置为什么?

标签: oracle sql-loader


【解决方案1】:

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

【讨论】:

  • 在使用模拟 Linux 终端时,上述解决方案对我来说效果很好,而不是在 CMD 上。
  • @Davi - export 在 Windows 中不起作用,但您可以使用 set 或在您的帐户设置下将它们设置为环境变量。
猜你喜欢
  • 2011-03-25
  • 1970-01-01
  • 2021-01-02
  • 2017-02-05
  • 2013-04-05
  • 2014-01-15
  • 1970-01-01
  • 2013-09-09
  • 2021-09-24
相关资源
最近更新 更多