【问题标题】:EDT and EST timestamp sqlldr data load in oracle在 oracle 中加载 EDT 和 EST 时间戳 sqlldr 数据
【发布时间】:2014-11-14 12:12:27
【问题描述】:

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

【问题讨论】:

    标签: oracle oracle11g timezone sql-loader


    【解决方案1】:

    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

    【讨论】:

      【解决方案2】:

      如果您无法更改文件中数据的格式,并且无法在加载文件之前对其进行操作,则可以将特定的 EDT 值替换为区域值 US/Eastern(或任何合适的值,例如 @ 987654323@) 与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】:

        对于那些来自其他国家的开发者,我想在这里引用askanydifference website

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

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

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

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-11-17
          • 1970-01-01
          • 2010-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-20
          相关资源
          最近更新 更多