使用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。请指导我...... :(
答案 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是否支持任何内联转换,例如从EST
到EST5EDT
答案 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/EASTERN
和EST
- 所以最好也可以更改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的基本理解在处理任何一种编程语言的开发过程中都有很长的路要走。