Oracle中的EDT和EST时间戳sqlldr数据加载

时间:2014-11-14 12:12:28

标签: oracle oracle11g timezone sql-loader

使用timestamp列通过sqlloader将数据从平面文件加载到Oracle数据库时遇到问题。 问题是我有EST和EDT的数据,如下面提到的格式

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。请指导我...... :(

3 个答案:

答案 0 :(得分:3)

EDT不是有效的时区区域,这是时区缩写。

有效区域是这些区域:

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

答案 1 :(得分: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的第一个名单中)。

答案 2 :(得分:0)

对于来自其他国家/地区的那些开发人员,我想在这里引用askanydifference website

东部标准时间与东部夏令时之间的主要区别 时间在于,尽管它们被同时使用 区域,它们在一年中的不同时间使用。

东部标准时间用于秋冬季节。它是 从11月的第一个星期日开始使用。

东部夏令时间也比东部标准时间早一小时 时间。

对EDT和EST的基本理解在处理任何一种编程语言的开发过程中都有很长的路要走。