2012-07-21 83 views
1

我有一个CSV文件列名为created与价值观:从CSV导入到Oracle时间戳

2012-04-16 14:46:42 
2012-06-16 12:40:52.653000000 

我试图导入到Oracle 11gR2的这种使用SQL Developer,07年3月1日

我以此作为格式:RRRR-MM-DD HH24:MI:SS.FF

我得到错误input value not long enough for the date format

如果我改变格式RRRR-MM-DD HH24:MI:SS我得到错误SQL Error: ORA-01830: date format picture ends before converting entire input string

我应该怎么做?

回答

3

你有一些日期和一些时间戳。这是从具有简单数据完整性的系统导入数据的问题。

您有两种选择:在导入之前清理数据或在导入期间清理数据。

预先清理数据有多种不同的方法。一种选择是使用支持正则表达式的文本处理器或IDE,并执行搜索并替换以修复缺少小数秒的那些值。

导入过程中最简单的清理方式是使用外部表作为中介(而不是SQL Loader)。外部表格是高度整洁的对象,它允许我们像操作数据库一样操作OS文件(如CSV)中的结构化数据。与SQL Loader相比,外部表的一大优点是我们可以在DML语句中使用它们。 Find out more

为此,您需要将该列的外部表定义为varchar2。您还需要构建一个函数,该函数接受一个字符串并将其转换为时间戳。

create or replace function fix_ts (str in varchar2) 
     return timestamp 
is 
     is_a_date exception; 
     pragma exception_init(is_a_date, -1840); 
     rv timestamp; 
begin 
     begin 
      rv := to_timestamp(str); 
     exception 
      when is_a_date then 
       rv := to_timestamp(str)||'.000000000'; 
     end; 
     return rv; 
end; 

然后,你可以插入记录INT目标表是这样的:

insert into target_table 
     (id, created, whatever) 
select id 
     , fix_ts(created) 
     , whatever 
from external_table; 

如果这是一个一次性的数据清洗运动,那么你可能会更好过在IDE改写(munging)数据。如果这是一个常规的数据馈送,那么值得一段时间来构建一些更加自治和强大的东西。


根据您的评论,还有第三个选项:让源系统在导出过程中修复数据。这可能很容易或很难,取决于许多因素;政治问题往往比技术问题更难以解决。

+0

伟大的答案谢谢,数据来自SQL Server SSIS。在阅读您的文章后,我决定尝试使用bcp.exe以不同方式从SQL Server中获取数据。这一次数据最终为.000,Oracle对导入感到满意。 – 2012-07-21 23:25:50