使用' AT TIME ZONE'进行时区转换的问题条款

时间:2014-05-02 16:36:21

标签: oracle oracle11g timezone

我有一个带有两列的Oracle 11g R2表:时区不可知的时间戳和文档时区如下:

EFF_START_DT                        TZ
31-DEC-08 09.00.00.000000000 PM     America/New_York
31-DEC-01 04.00.00.000000000 PM     Africa/Lome

我还有一个单独的表中定义的应用程序时区,我可以查询。 我需要将EFF_START_DT从应用程序时区转换为文档时区。

我的测试查询工作正常:

SELECT
EFF_START_DATE,
CAST(FROM_TZ(EFF_START_DATE, 'America/Los_Angeles') AT TIME ZONE TIMEZONE as date) AS EFF_DOC_START_DATE, 
TIMEZONE
FROM My_Tbl;

EFF_START_DT                    EFF_DOC_START_DT        TIMEZONE
31-DEC-08 09.00.00.000000000 PM 01-JAN-2009 00:00:00    America/New_York

我编写了Oracle行级功能来动态进行转换:

CREATE OR REPLACE FUNCTION MN_FROM_TZ(P_TIMESTAMP IN TIMESTAMP, P_TO_DOC_TZ IN VARCHAR2)
RETURN VARCHAR2
AS
V_TIMESTAMP_TZ VARCHAR2(50);
V_APP_TZ VARCHAR2(255);
BEGIN
  SELECT OPTION_VALUE INTO V_APP_TZ FROM MN_DW_ETL_CONFIG_OPTIONS WHERE  OPTION_NAME='APP_TIMEZONE';
  SELECT cast(FROM_TZ(P_TIMESTAMP, V_APP_TZ) AT TIME ZONE P_TO_DOC_TZ as date) INTO V_TIMESTAMP_TZ FROM DUAL;

RETURN V_TIMESTAMP_TZ;
END;

当我尝试运行它时,它成功编译:

SELECT EFF_START_DATE, MN_FROM_TZ(EFF_START_DATE, TIMEZONE) as EFF__DOC_START_DATE, TIMEZONE  FROM My_Tbl;

我收到以下错误:

ORA-00905: missing keyword
ORA-06512: at "ETLWINDM.MN_FROM_TZ", line 8
00905. 00000 -  "missing keyword"
*Cause:    
*Action:

问题似乎与P_TO_DOC_TZ参数有关。如果我将此参数硬编码为例如' America / New_York',则该功能正常工作。但我不能这样做,因为我表中的每一行都有不同的时区。我猜引号有问题但我无法找到答案。

1 个答案:

答案 0 :(得分:1)

令人惊讶的是,直接将值分配给变量而不是DUAL中的SELECT,可以解决问题。

SQLFiddle

CREATE OR REPLACE FUNCTION MN_FROM_TZ (P_TIMESTAMP   IN TIMESTAMP,
                                       P_TO_DOC_TZ   IN VARCHAR2)
   RETURN DATE
AS
   V_TIMESTAMP_TZ   DATE;
   V_APP_TZ         VARCHAR2 (255);
BEGIN
   SELECT app_tz INTO V_APP_TZ FROM t2;

   V_TIMESTAMP_TZ :=
      CAST (FROM_TZ (P_TIMESTAMP, V_APP_TZ) AT TIME ZONE P_TO_DOC_TZ AS DATE);

   RETURN V_TIMESTAMP_TZ;
END;
/

另请注意,V_TIMESTAMP_TZ的函数和数据类型的返回类型应为DATE,因为您在函数中将时间戳值转换为DATE。