oracle PL/SQL日期时间更新集结果时间00:00:00

8xiog9wr  于 2023-06-22  发布在  Oracle
关注(0)|答案(2)|浏览(194)

我试图设置一个datetime比end_ts datetime少一秒,如下所示

UPDATE Table1 SET 
          UPDTD_DT=(SELECT TO_DATE(END_TS-1/(24*60*60),'DD/MM/YYYY HH24:MI:SS')
          FROM View1) WHERE id = '123';

但在运行此更新后,日期时间为00:00:00。我显示并检查了TO_DATE(END_TS-1/(246060),'DD/MM/YYYY HH 24:MI:SS'),它看起来很好。

SELECT TO_DATE(END_TS-1/(24*60*60),'DD/MM/YYYY HH24:MI:SS') FROM View1 is 25/03/2022 10:14:44

任何建议将不胜感激。

wtzytmuj

wtzytmuj1#

切勿在已经是DATE(或TIMESTAMP)的值上使用TO_DATE。在最好的情况下,它什么也不做,在最坏的情况下,它将引发一个异常,或者正如您发现的那样,给予一个意外的输出。

您需要:

UPDATE Table1
SET   UPDTD_DT = (SELECT END_TS - INTERVAL '1' SECOND FROM View1)
WHERE id       = '123';
  • 或者用1/(24*60*60)代替INTERVAL '1' SECOND,但后者可能更容易理解您在代码审查期间的意思。

如果您用途:

SELECT TO_DATE(END_TS-1/(24*60*60),'DD/MM/YYYY HH24:MI:SS')
FROM   View1

并且END_TSDATE列,那么TO_DATE需要一个字符串作为它的第一个参数,所以在转换回DATE之前,你的DATE值将被隐式转换为字符串,使用默认的格式模型进行日期到字符串的转换(NLS_DATE_FORMAT会话参数),查询实际上是:

SELECT TO_DATE(
         TO_CHAR(
           END_TS-1/(24*60*60),
           (SELECT value FROM NLS_SESSION_PARAMETERS WHERE parameter = 'NLS_DATE_FORMAT')
         ),
         'DD/MM/YYYY HH24:MI:SS'
       )
FROM   View1

如果NLS_DATE_FORMAT'DD/MM/YYYY HH24:MI:SS'模型不匹配,则会出现异常。如果它匹配但不显示时间分量(即NLS_DATE_FORMATDD/MM/YYYY),则将使用午夜的默认时间分量。
理论上,您可以通过更改用户的NLS_DATE_FORMAT会话参数来解决此问题:

ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS';

但是,您需要为每个运行查询的用户设置它,并且用户可以随时更改自己的会话参数,因此您必须确保每次运行查询时都设置它。因此,这并不被认为是一种良好的做法。
更好的做法是不将TO_DATE用于DATE值,并避免隐式转换为字符串。
fiddle

gz5pxeao

gz5pxeao2#

发生这种情况的原因是您正在对DATE类型的列执行TO_DATE。没有必要那样做。
检查以下示例(TO_CHAR换行仅用于显示目的):

SELECT TO_CHAR(
         TO_DATE(sysdate-1/(24*60*60),'DD/MM/YYYY HH24:MI:SS'),
         'DD-MON-YYYY HH24:MI') as unneeded_todate,
       TO_CHAR(
         sysdate-1/(24*60*60),
         'DD-MON-YYYY HH24:MI') as correct_code         
  FROM dual;

UNNEEDED_TODATE            CORRECT_CODE              
-------------------------- --------------------------
12-JUN-2023 00:00          12-JUN-2023 08:06

为了解决你的问题:

UPDATE Table1 SET 
          UPDTD_DT=(SELECT END_TS-1/(24*60*60)
          FROM View1) WHERE id = '123';

或者...使用INTERVAL进行加/减。

UPDATE Table1 
   SET 
        UPDTD_DT= (SELECT END_TS - INTERVAL '1' SECOND
                     FROM View1) 
WHERE id = '123';

相关问题