2012-07-21 117 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