1

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

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

我该怎么做?

4

1 回答 1

3

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

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

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

导入期间最简单的清理方法是使用外部表作为中介(而不是 SQL 加载器)。外部表是高度整洁的对象,允许我们像在数据库中一样操作 OS 文件(例如 CSV)中的结构化数据。与 SQL Loader 相比,外部表的最大优势在于我们可以在 DML 语句中使用它们。 了解更多

为此,您需要将该列定义为 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 中处理数据。如果这是一个常规的数据馈送,那么构建更自主和更强大的东西是值得的。


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

于 2012-07-21T20:18:57.897 回答