我有一个带有两列的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',则该功能正常工作。但我不能这样做,因为我表中的每一行都有不同的时区。我猜引号有问题但我无法找到答案。
答案 0 :(得分:1)
令人惊讶的是,直接将值分配给变量而不是DUAL中的SELECT,可以解决问题。
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。