我在名为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
我该怎么做?
答案 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中修改数据。如果这是一个常规数据馈送,那么构建更自主和更强大的东西是值得的。
根据您的评论,还有第三种选择:让源系统在导出过程中修复数据。根据许多因素,这可能很容易或很困难;政治问题往往比技术问题难以解决。