2014-11-14 121 views
0

我通過sqlloader通過Timestamp列將數據從平面文件加載到Oracle數據庫時遇到問題。 問題是我有兩個EST和EDT數據類似下面的格式EDT和EST時間戳oracle中的sqlldr數據加載

test_data.dat

Thu Mar 07 14:27:14 EST 2013 
Thu Mar 07 14:27:27 EST 2013 
Tue Apr 09 18:20:54 EDT 2013 
Tue Apr 09 18:24:26 EDT 2013 

我sqldrfile.ctl代碼如下

LOAD DATA 
INFILE 'test_data.dat' 
TRUNCATE 
INTO TABLE MY_TABLE FIELDS TERMINATED BY '|' 
TRAILING NULLCOLS 
(
     "DOC_DATE_ADDED" TIMESTAMP WITH TIME ZONE "DY MON DD HH24:MI:SS TZR YYYY", 
) 

Rejected_data.bad以下兩條記錄無法識別並轉到壞檔案

Tue Apr 09 18:20:54 EDT 2013 
Tue Apr 09 18:24:26 EDT 2013 

其他兩個EST記錄正確加載到oracle表中我需要一個sqlldr代碼來加載時間戳EST和EDT。請指導我這個.. :(

回答

2

如果您不能更改文件中的數據格式,在加載之前無法操作的文件,你可以替換範圍價值US/Eastern(或任何合適的特定EDT值像America/New_York值)an SQL operator

"DOC_DATE_ADDED" TIMESTAMP WITH TIME ZONE "DY MON DD HH24:MI:SS TZR YYYY" 
    "REPLACE(:DOC_DATE_ADDED, 'EDT', 'US/Eastern')" 

(分成兩行的可讀性,但你可以做的是,在控制文件也是如此)。

當你的樣本數據文件被加載表包含:

select to_char(doc_date_added, 'YYYY-MM-DD HH24:MI:SS TZD') as TZD, 
    to_char(doc_date_added, 'YYYY-MM-DD HH24:MI:SS TZR') as TZR 
from my_table; 

TZD      TZR       
----------------------- ------------------------------ 
2013-03-07 14:27:14 EST 2013-03-07 14:27:14 EST   
2013-03-07 14:27:27 EST 2013-03-07 14:27:27 EST   
2013-04-09 18:20:54 EDT 2013-04-09 18:20:54 US/EASTERN 
2013-04-09 18:24:26 EDT 2013-04-09 18:24:26 US/EASTERN 

...所以你保留EST/EDT分割;雖然TZR顯示US/EASTERNEST - 所以它可能是更好的改變EST價值,以及與嵌套REPLACE或:

"DOC_DATE_ADDED" TIMESTAMP WITH TIME ZONE "DY MON DD HH24:MI:SS TZR YYYY" 
    "REGEXP_REPLACE(:DOC_DATE_ADDED, 'E[SD]T', 'US/Eastern')" 

或者,如果所有的值總是EST/EDT,你可以做時間戳轉換明確,只是切出你給出的實際字符串:它加載您的數據

"DOC_DATE_ADDED" CHAR "FROM_TZ(TO_TIMESTAMP(SUBSTR(:DOC_DATE_ADDED, 1, 19) 
    || SUBSTR(:DOC_DATE_ADDED, 25, 29), 'DY MON DD HH24:MI:SS YYYY'), 'US/Eastern')" 

TZD      TZR       
----------------------- ------------------------------ 
2013-03-07 14:27:14 EST 2013-03-07 14:27:14 US/EASTERN 
2013-03-07 14:27:27 EST 2013-03-07 14:27:27 US/EASTERN 
2013-04-09 18:20:54 EDT 2013-04-09 18:20:54 US/EASTERN 
2013-04-09 18:24:26 EDT 2013-04-09 18:24:26 US/EASTERN 

這樣做的危險是,如果您曾經在不同的時區獲得價值,它會默默地記錄在錯誤的地區,而第一個版本將成功處理或拒絕,取決於它是否被識別(即在Wernfried的第一份名單中)。

3

EDT IST不是一個有效的時區區域,這是一個時區縮寫

有效的區域是這些的:

SELECT * 
FROM V$TIMEZONE_NAMES 
WHERE TZNAME = TZABBREV; 

TZNAME TZABBREV 
====================== 
CET  CET 
CST  CST 
EET  EET 
EST  EST 
GMT  GMT 
HST  HST 
MET  MET 
MST  MST 
PST  PST 
WET  WET 

原因你可以看到這個查詢EDT可能代表UTC-04:00到UTC-06:00的幾個不同的時區區域

SELECT TZNAME, TZ_OFFSET(TZNAME) 
FROM V$TIMEZONE_NAMES 
WHERE TZABBREV = 'EDT' 
ORDER BY 2; 

TZNAME       TZ_OFFSET(TZNAME) 
------------------------------- ----------------- 
America/Santo_Domingo     -04:00   
America/Fort_Wayne      -05:00   
America/Grand_Turk      -05:00   
America/Indiana/Indianapolis    -05:00   
America/Indiana/Marengo     -05:00   
America/Indiana/Petersburg    -05:00   
US/Michigan        -05:00   
America/Detroit       -05:00   
US/Eastern        -05:00   
America/Indiana/Vevay     -05:00   
America/Indiana/Vincennes    -05:00   
America/Indiana/Winamac     -05:00   
America/Indianapolis      -05:00   
America/Iqaluit       -05:00   
America/Jamaica       -05:00   
America/Kentucky/Louisville    -05:00   
America/Kentucky/Monticello    -05:00   
America/Louisville      -05:00   
America/Montreal       -05:00   
America/Nassau       -05:00   
America/New_York       -05:00   
America/Nipigon       -05:00   
America/Pangnirtung      -05:00   
America/Port-au-Prince     -05:00   
America/Thunder_Bay      -05:00   
America/Toronto       -05:00   
Canada/Eastern       -05:00   
EST5EDT         -05:00   
Jamaica         -05:00   
US/East-Indiana       -05:00   
America/Cancun       -06:00   
America/Indiana/Tell_City    -06:00   

32 rows selected. 

我假設你必須修改你的文本文件。我不知道sqlloader是否支持任何內嵌轉換,例如從ESTEST5EDT