我试图设置一个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
任何建议将不胜感激。
2条答案
按热度按时间wtzytmuj1#
切勿在已经是
DATE
(或TIMESTAMP
)的值上使用TO_DATE
。在最好的情况下,它什么也不做,在最坏的情况下,它将引发一个异常,或者正如您发现的那样,给予一个意外的输出。您需要:
1/(24*60*60)
代替INTERVAL '1' SECOND
,但后者可能更容易理解您在代码审查期间的意思。如果您用途:
并且
END_TS
是DATE
列,那么TO_DATE
需要一个字符串作为它的第一个参数,所以在转换回DATE
之前,你的DATE
值将被隐式转换为字符串,使用默认的格式模型进行日期到字符串的转换(NLS_DATE_FORMAT
会话参数),查询实际上是:如果
NLS_DATE_FORMAT
与'DD/MM/YYYY HH24:MI:SS'
模型不匹配,则会出现异常。如果它匹配但不显示时间分量(即NLS_DATE_FORMAT
是DD/MM/YYYY
),则将使用午夜的默认时间分量。理论上,您可以通过更改用户的
NLS_DATE_FORMAT
会话参数来解决此问题:但是,您需要为每个运行查询的用户设置它,并且用户可以随时更改自己的会话参数,因此您必须确保每次运行查询时都设置它。因此,这并不被认为是一种良好的做法。
更好的做法是不将
TO_DATE
用于DATE
值,并避免隐式转换为字符串。fiddle
gz5pxeao2#
发生这种情况的原因是您正在对
DATE
类型的列执行TO_DATE
。没有必要那样做。检查以下示例(TO_CHAR换行仅用于显示目的):
为了解决你的问题:
或者...使用
INTERVAL
进行加/减。