蟾蜍不要把时间还给我

Posted

技术标签:

【中文标题】蟾蜍不要把时间还给我【英文标题】:Toad dont return me the time 【发布时间】:2020-09-24 08:08:51 【问题描述】:

我的日期转换有问题,当我执行这部分代码时,它只返回没有时间的日期:

DECLARE
        vdate VARCHAR2(255);
BEGIN  
        select cast(TO_TIMESTAMP_TZ('2020-09-23T03:02:00+02:00','yyyy-mm-dd"T"hh24:mi:ss"+"TZH:TZM') as date) into vdate from dual; 
        DBMS_OUTPUT.PUT_LINE(vdate);
END;

这只返回我:

23-SEP-20

如何获取日期和时间?谢谢

【问题讨论】:

@Abra 我试过了,但我得到了“INVALID NUMBER”错误 【参考方案1】:
DECLARE
  vdate VARCHAR2(255);
BEGIN  
  select cast(
           TO_TIMESTAMP_TZ(
             '2020-09-23T03:02:00+02:00',
             'yyyy-mm-dd"T"hh24:mi:ssTZH:TZM' -- remove the "+"
           )
           as date
         )
  into   vdate
  from   dual;

  DBMS_OUTPUT.PUT_LINE(vdate);
END;
/

您从字符串 (2020-09-23T03:02:00+02:00) 转到时间戳(使用 TO_TIMESTAMP_TZ 函数,您不应该显式匹配 + 字符,而应该让 TZH 格式模型匹配它) 然后到一个日期,然后将其放入一个字符串变量中,该变量需要从二进制日期值隐式转换为字符串。这一切似乎都是多余的。但是,正是这最后一步,即从日期到字符串的隐式转换,导致了您的问题,因为 Oracle 将使用 NLS_DATE_FORMAT 会话参数作为格式模型进行转换。

解决这个问题的一种方法是使用:

ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD"T"HH24:MI:SS';

然后您的代码应该输出正确的值而无需更改您的代码。

但是,您不应该使用此方法,因为它依赖于用户更改会话,并且大多数用户不会这样做(如果他们这样做,那么他们很可能会更改将其转换为他们喜欢的日期格式,而不是您想要的日期格式,这会再次打破您对代码行为的期望)。

相反,如果您需要特定格式或日期,则应使用 TO_CHAR 明确应用该格式:

BEGIN  
  DBMS_OUTPUT.PUT_LINE(
    TO_CHAR(
      TO_TIMESTAMP_TZ(
        '2020-09-23T03:02:00+02:00',
        'yyyy-mm-dd"T"hh24:mi:ssTZH:TZM'
      ),
      'YYYY-MM-DD"T"HH24:MI:SS'
    )
  );
END;
/

(注意:您不需要:声明变量;使用 SQL;或转换为日期。相反,您可以在一行中完成所有操作。)

如果您确实想使用变量,那么您可以在 PL/SQL 中通过将值直接分配给变量来完成所有操作(并且不需要上下文切换来使用 SQL 引擎):

DECLARE
  vdate DATE;
BEGIN
  vdate := TO_TIMESTAMP_TZ(
             '2020-09-23T03:02:00+02:00',
             'yyyy-mm-dd"T"hh24:mi:ssTZH:TZM'
           );

  DBMS_OUTPUT.PUT_LINE( TO_CHAR( vdate, 'YYYY-MM-DD"T"HH24:MI:SS' ) );
END;
/

db小提琴here

【讨论】:

谢谢,但这个解决方案对我不起作用,我需要这样的结果:23-SEPT.-20 03:02:00,当我用 TO_DATE(vdate,' 转换你的结果时YYYY-MM-DD HH24:MI:SS');我只有日期没有时间 @mysqlDev788 在我的最后一个示例中,vdate 已经是 DATE 类型;你不需要(也不应该)在上面使用TO_DATE。我想要一个特定的格式字符串,然后使用适当的format model 和TO_CHAR,例如DBMS_OUTPUT.PUT_LINE( TO_CHAR( vdate, 'DD-MON-RR HH24:MI:SS' ) ); 我需要将其转换为日期,因为我在日期列中的表中进行了更新 @MySqlDev788 vdate 被声明为 DATE 数据类型。使用TO_TIMESTAMP_TZ 会为您提供TIMESTAMP WITH TIME ZONE 数据类型,然后将其分配给vdate 变量,然后Oracle 会将其隐式转换为DATE。您不需要做任何其他事情,因为 vdate 已经是 DATE .... 只需使用它的值并将其插入表中,无需任何进一步的转换(除非您需要转换为标准时区,例如 UTC +0)。【参考方案2】:

在 Toad 中,您可以在 查看 -> Toad 选项 下设置日期格式掩码。我的截图来自 Toad 13.2.0.258。

【讨论】:

以上是关于蟾蜍不要把时间还给我的主要内容,如果未能解决你的问题,请参考以下文章

大脑能存储,但不要把它当做磁盘用

蟾蜍plsql错误执行存储过程

SQL 和蟾蜍

我把师父陪工地的钱还给师父可是师父没有要

为了让医院把医护还给患者,他们用了这个…

把复杂交给我们,把简单还给你丨TiVP 让 SQL 执行计划可视化