从csv导入到Oracle时间戳

时间:2012-07-21 19:08:22

标签: oracle import oracle11g type-conversion

我在名为created的csv文件中有一个列,值为:

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

我正在尝试使用SQL Developer 3.1.07将其导入Oracle 11gR2

我将其用作格式: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

我该怎么做?

1 个答案:

答案 0 :(得分: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;

然后你可以在目标表中插入记录,如下所示:

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

如果这是一次性数据清理练习,那么您可能最好在IDE中修改数据。如果这是一个常规数据馈送,那么构建更自主和更强大的东西是值得的。


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