我们正在尝试将FastExport创建的文件加载到oracle数据库中。
但是,Float列的输出方式如下:1.47654345670000000000 E010
。
您如何配置SQL * Loader像这样导入它。
期望控制脚本如下所示:
OPTIONS(DIRECT=TRUE, ROWS=20000, BINDSIZE=8388608, READSIZE=8388608)
UNRECOVERABLE LOAD DATA
infile 'data/SOME_FILE.csv'
append
INTO TABLE SOME_TABLE
fields terminated by ','
OPTIONALLY ENCLOSED BY '"' AND '"'
trailing nullcols (
FLOAT_VALUE CHAR(38) "???????????????????",
FILED02 CHAR(5) "TRIM(:FILED02)",
FILED03 TIMESTAMP "YYYY-MM-DD HH24:MI:SS.FF6",
FILED04 CHAR(38)
)
我尝试了
to_number('1.47654345670000000000 E010', '9.99999999999999999999 EEEE')
我尝试了
to_number('1.47654345670000000000 E010', '9.99999999999999999999EEEE')
这些是我按优先顺序提出的解决方案:
to_number(replace('1.47654345670000000000 E010', ' ', ''))
to_number(TRANSLATE('1.47654345670000000000 E010', '1 ', '1'))
我想知道是否有更好的解决方案。
最佳答案
据我所知,没有办法让to_number
忽略该空间,并且您无法在SQL * Loader中进行任何准备。如果不能通过预处理文件将其删除(建议不要这样做),则必须在某个时候使用字符串函数。我不希望它会增加大量的处理,无论如何to_number都会做,但是我总是会尝试并观察而不是假设任何事情-避免字符串函数听起来有点像过早的优化。无论如何,最简单的可能是replace
:
select to_number(replace('1.47654345670000000000 E010',' ',''),
'9.99999999999999999999EEEE') from dual;
或仅用于显示目的:
column num format 99999999999
select to_number(replace('1.47654345670000000000 E010',' ',''),
'9.99999999999999999999EEEE') as num from dual
NUM
------------
14765434567
您可以定义自己的函数来稍微简化控制文件,但不确定是否值得。
我想到了另外两个选择。 (a)以
varchar
的形式加载到临时表中,然后使用to_number(replace())
填充实际表;但我怀疑这会不会改善性能,并且可能会变得更糟。或(b)如果您正在运行11g,则将其加载到实际表中的varchar
列中,并将您的数字列设置为应用该功能的virtual column。实际上,第三个选项...根本不使用SQLLoader,而是将CSV文件用作外部表,并从中填充您的实际表。您仍然必须执行
to_number(replace())
,但与在SQLLoader中执行此操作相比,您可能会发现性能有所不同。区别可能是,情况当然更糟,但可能值得尝试。关于sql - 您如何从Oracle SQL中的科学计数法转换?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9505369/