带有 TIMESTAMP 的 ORACLE 过程

ORACLE Procedure with TIMESTAMP

我尝试编写一个程序来了解从一个时区到另一个时区的日期时间 我无法编译,因为格式日期无效而且我不知道如何管理变量。 你能给我一个小费吗

    create or replace PROCEDURE DATETIME_FROM_TO
(
    VALUE$DATETIME in date, 
    VALUE$FROM in varchar2,
    VALUE$TO in varchar2,
    FLAG in number
) AS  c1 SYS_REFCURSOR;  
    begin
        VALUE_DATETIME := VALUE$DATETIME;
        VALUE_FROM := VALUE$FROM;
        VALUE_TO := VALUE$TO;
        if FLAG=12 then
            open c1 for            
            select to_char(from_tz(TIMESTAMP 'VALUE_DATETIME', 'VALUE$FROM') at time zone 'VALUE$TO','DD/MM/YYYY HH:MI PM') as localtime into c1 from dual;
        else
            open c1 for
            select to_char(from_tz(TIMESTAMP 'VALUE$DATETIME', 'VALUE$FROM') at time zone 'VALUE$TO','DD/MM/YYYY HH24:MI') as localtime into c1 from dual;
        end if;
        DBMS_SQL.RETURN_RESULT(c1);
        close c1;
    end;

谢谢

我不确定您为什么要使用游标并return在结果集中输入字符串这一极其复杂的路线。

只需编写一个简单的函数,它接受一个 TIMESTAMP 参数(如果你传递一个 DATE 它将被隐式转换为一个 TIMESTAMP)并且如果你想格式化它作为字符串,那么您可以根据需要在 return 值上调用 TO_CHAR

CREATE FUNCTION change_timezone(
  i_datetime TIMESTAMP,
  i_from_tz  VARCHAR2,
  i_to_tz    VARCHAR2
) RETURN TIMESTAMP WITH TIME ZONE DETERMINISTIC
IS
BEGIN
  RETURN FROM_TZ( i_datetime, i_from_tz ) AT TIME ZONE i_to_tz;
END;
/

然后你可以调用它:

SELECT change_timezone( DATE '1970-01-01', 'UTC', 'Europe/Berlin' )
FROM   DUAL;

哪些输出(取决于您的 NLS_TIMESTAMP_TZ_FORMAT 设置):

| EPOCH_TIME_IN_GERMANY             |
| :-------------------------------- |
| 1970-01-01 01:00:00.000000000 CET |

如果您希望它具有特定格式,则:

SELECT TO_CHAR(
         change_timezone( DATE '1970-01-01', 'UTC', 'Europe/Berlin' ),
         'DD/MM/YYYY HH12:MI PM'
       ) AS formatted_epoch_time_in_germany
FROM   DUAL;

输出:

| FORMATTED_EPOCH_TIME_IN_GERMANY |
| :------------------------------ |
| 01/01/1970 01:00 AM             |

如果你真的想合并字符串转换(不要,在函数外进行转换)那么你可以使用:

CREATE FUNCTION format_as_timezone(
  i_datetime TIMESTAMP,
  i_from_tz  VARCHAR2,
  i_to_tz    VARCHAR2,
  i_use_24hr NUMBER DEFAULT 1
) RETURN VARCHAR2 DETERMINISTIC
IS
BEGIN
  RETURN TO_CHAR(
    FROM_TZ( i_datetime, i_from_tz ) AT TIME ZONE i_to_tz,
    CASE i_use_24hr
    WHEN 1
    THEN 'DD/MM/YYYY HH24:MI'
    ELSE 'DD/MM/YYYY HH12:MI AM'
    END
  );
END;
/

db<>fiddle here