我正在尝试将以下Teradata SQL转换为Oracle。问题是我无法在Oracle中找到等效的时区值。在下面的例子中,' Europe Central'在Oracle中无法识别。
select hi.create_date
, to_char( hi.create_date,'YYYY-MM-DD HH24:MI:SS')
, ((CAST(to_char( hi.create_date,'YYYY-MM-DD HH24:MI:SS')||'+00:00' AS TIMESTAMP(0))) at time zone 'Europe Central')
from historical_info hi
Oracle中的以下代码会引发错误:
SELECT create_date,
CAST( create_date
AS TIMESTAMP WITH TIME ZONE
) AT TIME ZONE 'Europe Central'
TZ_LOSANG
FROM historical_info
ORA-01878: specified field not found in datetime or interval.
01878. 00000 - "specified field not found in datetime or interval"
*Cause: The specified field was not found in the datetime or interval.
*Action: Make sure that the specified field is in the datetime or interval.
您能否帮我转换Teradata时区到Oracle认可的时区。
答案 0 :(得分:1)
您可以获得支持的时区列表as shown in the documentaion:
您可以通过输入以下语句从数据库中安装的时区文件中获取时区名称和时区缩写列表:
SELECT TZNAME, TZABBREV FROM V$TIMEZONE_NAMES ORDER BY TZNAME, TZABBREV;
将Teradata名称转换为Oracle名称并不是简单的内置方式,因此您需要为每个需要处理的区域/区域选择合适的等效项。
甲骨文没有“欧洲/中部地区”。时区名称,但确实识别CET缩写,或者映射到该缩写的任何名称:
alter session set nls_timestamp_tz_format = 'YYYY-MM-DD HH24:MI:SS TZR';
with historical_info(create_date) as (select sysdate from dual)
SELECT create_date,
CAST(create_date AS TIMESTAMP) AT TIME ZONE 'CET' TZ_AT_CET
FROM historical_info;
CREATE_DATE TZ_AT_CET
------------------- -----------------------
2015-08-17 11:59:29 2015-08-17 12:59:29 CET
但这是调整从我的会话时区到CET的时间,这可能不是你想要的。如果您说存储的时间代表CET,那么您需要from_tz
函数:
SELECT create_date,
CAST(create_date AS TIMESTAMP) AT TIME ZONE 'CET' TZ_AT_CET,
FROM_TZ(CAST(create_date AS TIMESTAMP), 'CET') TZ_FROM_CET
FROM historical_info;
CREATE_DATE TZ_AT_CET TZ_FROM_CET
------------------- ----------------------- -----------------------
2015-08-17 12:01:40 2015-08-17 13:01:40 CET 2015-08-17 12:01:40 CET
从您的列别名中,您可能会尝试在不同的区域中显示CET时间,这需要两个步骤:
SELECT create_date,
FROM_TZ(CAST(create_date AS TIMESTAMP), 'CET') TZ_FROM_CET,
FROM_TZ(CAST(create_date AS TIMESTAMP), 'CET')
AT TIME ZONE 'America/Los_Angeles' TZ_LOSANG
FROM historical_info
CREATE_DATE TZ_FROM_CET TZ_LOSANG
------------------- ----------------------- ---------------------------------------
2015-08-17 12:02:55 2015-08-17 12:02:55 CET 2015-08-17 03:02:55 AMERICA/LOS_ANGELES
如果您的行具有不同的区域,并且此类目前存储为单独的列,则可以使用案例表达式(或解码)为每个区域指定Oracle等效项;但是你还是要自己做这个映射。如果这不是一次性任务,您可以将翻译放入查找表。
with historical_info(create_date, orig_zone) as (
select sysdate, 'Europe Central' from dual
union all select sysdate, 'Europe Western' from dual
union all select sysdate, 'America Central' from dual
)
SELECT create_date,
FROM_TZ(CAST(create_date AS TIMESTAMP),
case orig_zone
when 'Europe Central' then 'CET'
when 'Europe Western' then 'WET'
when 'America Central' then 'US/Central'
-- when x then y for all other values you need
end) TZ_ADJUSTED
FROM historical_info
CREATE_DATE TZ_ADJUSTED
------------------- --------------------------------------
2015-08-17 12:16:13 2015-08-17 12:16:13 CET
2015-08-17 12:16:13 2015-08-17 12:16:13 WET
2015-08-17 12:16:13 2015-08-17 12:16:13 US/CENTRAL
您需要小心使用适当调整夏令时的时区(或缩写)。