varchar2 中的 Oracle 时间(例如 21:03:18)到数字

Oracle time (eg. 21:03:18) in varchar2 to number

我的数据库中的时间列有问题。我创建了程序来调整夏令时和冬令时,我像下面那样使用它,但它是非常慢的解决方案,我必须等待超过一分钟才能收到这种情况的报告,没有它执行时间是~4秒

CASE WHEN i.created_on BETWEEN get_first_day_of_spring(EXTRACT(year FROM i.created_on)) AND get_first_day_of_fall(EXTRACT(year FROM i.created_on)) 
    THEN to_char(substr(REPLACE(i.time_,':',''),1,2)+2||':'||substr(REPLACE(i.time_,':',''),3,2)||':'|| substr(REPLACE(i.time_,':',''),5,2))
    ELSE to_char(substr(REPLACE(i.time_,':',''),1,2)+1||':'||substr(REPLACE(i.time_,':',''),3,2)||':'|| substr(REPLACE(i.time_,':',''),5,2))

是否有任何方法可以将数据库类型从 vachar2 更改为数字?

不要使用字符串函数,将字符串转换为 TIMESTAMP WITH TIME ZONE 数据类型,然后使用 AT TIME ZONE <your timezone> 将其转换为预期输出。

例如,如果您的数据存储在 UTC 时区的 table,而您希望它在您当地的时区,例如 Europe/Berlin,那么:

SELECT created_on,
       time_,
       TO_CHAR(
         TO_TIMESTAMP_TZ(
           created_on || time_ || ' UTC',
           'YYYY-MM-DDHH24:MI:SS TZD'
         ) AT TIME ZONE 'Europe/Berlin',
         'YYYY-MM-DD'
       ) AS dst_date_germany,
       TO_CHAR(
         TO_TIMESTAMP_TZ(
           created_on || time_ || ' UTC',
           'YYYY-MM-DDHH24:MI:SS TZD'
         ) AT TIME ZONE 'Europe/Berlin',
         'HH24:MI:SS'
       ) AS dst_time_germany
FROM   table_name

其中,对于示例数据:

CREATE TABLE table_name ( created_on, time_ ) AS
SELECT '2021-01-01', '00:00:00' FROM DUAL UNION ALL
SELECT '2021-03-27', '23:00:00' FROM DUAL UNION ALL
SELECT '2021-03-28', '00:00:00' FROM DUAL UNION ALL
SELECT '2021-03-28', '02:00:00' FROM DUAL UNION ALL
SELECT '2021-10-31', '00:00:00' FROM DUAL UNION ALL
SELECT '2021-10-31', '02:00:00' FROM DUAL;

输出:

CREATED_ON | TIME_    | DST_DATE_GERMANY | DST_TIME_GERMANY
:--------- | :------- | :--------------- | :---------------
2021-01-01 | 00:00:00 | 2021-01-01       | 01:00:00        
2021-03-27 | 23:00:00 | 2021-03-28       | 00:00:00        
2021-03-28 | 00:00:00 | 2021-03-28       | 01:00:00        
2021-03-28 | 02:00:00 | 2021-03-28       | 04:00:00        
2021-10-31 | 00:00:00 | 2021-10-31       | 02:00:00        
2021-10-31 | 02:00:00 | 2021-10-31       | 03:00:00        

更好的是,将您的 created_ontime_ 字符串列合并到具有 DATETIMESTAMP 数据类型的单个 created_on 列中,然后您可以在时区之间转换。

ALTER TABLE table_name ADD ( created_on2 DATE );
UPDATE table_name
SET created_on2 = TO_DATE( created_on || time_, 'YYYY-MM-DDHH24:MI:SS' );
ALTER TABLE table_name DROP COLUMN created_on;
ALTER TABLE table_name DROP COLUMN time_;
ALTER TABLE table_name RENAME COLUMN created_on2 TO created_on;

然后:

SELECT created_on,
       FROM_TZ( CAST( created_on AS TIMESTAMP ), 'UTC' )
         AT TIME ZONE 'Europe/Berlin'
         AS dst_germany
FROM   table_name

输出:

CREATED_ON          | DST_GERMANY                    
:------------------ | :------------------------------
2021-01-01 00:00:00 | 2021-01-01 01:00:00.000000 CET 
2021-03-27 23:00:00 | 2021-03-28 00:00:00.000000 CET 
2021-03-28 00:00:00 | 2021-03-28 01:00:00.000000 CET 
2021-03-28 02:00:00 | 2021-03-28 04:00:00.000000 CEST
2021-10-31 00:00:00 | 2021-10-31 02:00:00.000000 CEST
2021-10-31 02:00:00 | 2021-10-31 03:00:00.000000 CET 

db<>fiddle here