I am trying to set a datetime one second less than the end_ts datetime with sql as below
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';
But after ran this update, the datetime is 00:00:00. I displayed and checked the TO_DATE(END_TS-1/(246060),'DD/MM/YYYY HH24:MI:SS') which looks fine.
SELECT TO_DATE(END_TS-1/(24*60*60),'DD/MM/YYYY HH24:MI:SS') FROM View1 is 25/03/2022 10:14:44
Any advice would be highly appreciated.
NEVER use TO_DATE
on a value that is already a DATE
(or TIMESTAMP
). At best, it will do nothing and, at worst, it will raise an exception or, as you are finding, give an unexpected output.
You want:
UPDATE Table1
SET UPDTD_DT = (SELECT END_TS - INTERVAL '1' SECOND FROM View1)
WHERE id = '123';
Or 1/(24*60*60)
instead of INTERVAL '1' SECOND
, but the latter is probably easier to comprehend what you mean during a code review.
If you use:
SELECT TO_DATE(END_TS-1/(24*60*60),'DD/MM/YYYY HH24:MI:SS')
FROM View1
and END_TS
is a DATE
column then TO_DATE
expects a string as its first argument so your DATE
value will be implicitly cast to a string using the default format model for date-to-string conversions (the NLS_DATE_FORMAT
session parameter) before being converted back to a DATE
and the query is effectively:
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
If the NLS_DATE_FORMAT
does not match the 'DD/MM/YYYY HH24:MI:SS'
format model then you will get an exception. If it does match but does not display the time component (i.e. the NLS_DATE_FORMAT
is DD/MM/YYYY
) then the default time component of midnight will be used.
Theoretically, you could solve the problem by changing the user's NLS_DATE_FORMAT
session parameter:
ALTER SESSION SET NLS_DATE_FORMAT = 'DD/MM/YYYY HH24:MI:SS';
But then you would need to set it for every user who runs the query and users can change their own session parameters at any time so you would have to ensure it is set each time you run the query. So this is not considered good practice.
It is considered better practice to not use TO_DATE
to a DATE
value and avoid the implicit cast to a string.