Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

ORA-01841: (full) year must be between -4713 and +9999, and not be 0 when using the lead function

I have been working on a query and couldn’t figure out the solution for this error. Hope can get insights from the community on how to solve this:

select TO_TIMESTAMP(to_char(RTC_TIMESTAMP, 'yyyy-mm-dd hh24:mi:ss') || ',' || lpad(rtc_event_order_seq, 3, '0'), 'YYYY-MM-DD HH24:MI:SS,FF3') AS TIME_STAMP,
TO_TIMESTAMP(to_char((Lead(RTC_TIMESTAMP,1)over(order by RTC_TIMESTAMP)), 'yyyy-mm-dd hh24:mi:ss') || ',' || lpad(rtc_event_order_seq, 3, '0'), 'YYYY-MM-DD HH24:MI:SS,FF3') AS NEXT_TIMESTAMP
from mytable

the Error I have been getting is:

ora-01841 full year must be between 4713 and 9999 and not be 0

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

The problem is with the final row in the result set, when there is no lead row to get values from. Lead(RTC_TIMESTAMP,1)over(order by RTC_TIMESTAMP) returns null, you concatenate a comma and milliseconds value. The next_timestamp calculation ends up as:

TO_TIMESTAMP(',001', 'YYYY-MM-DD HH24:MI:SS,FF3')

which is what throws that error. You can see that if you run the query without the to_timestamp() calls.

The value is probably wrong anyway – presumably you should be looking at the lead rtc_event_order_seq as well – which would also be null, by trying to convert ',' would also fail.

You can wrap the next_timestamp is a case expression to avoid the issue:

select TO_TIMESTAMP(to_char(RTC_TIMESTAMP, 'yyyy-mm-dd hh24:mi:ss') || ',' || lpad(rtc_event_order_seq, 3, '0'), 'YYYY-MM-DD HH24:MI:SS,FF3') AS TIME_STAMP,
  case when Lead(RTC_TIMESTAMP,1)over(order by RTC_TIMESTAMP) is not null then
    TO_TIMESTAMP(to_char((Lead(RTC_TIMESTAMP,1)over(order by RTC_TIMESTAMP)), 'yyyy-mm-dd hh24:mi:ss')
      || ',' || lpad(Lead(rtc_event_order_seq,1)over(order by RTC_TIMESTAMP), 3, '0'), 'YYYY-MM-DD HH24:MI:SS,FF3')
    end AS NEXT_TIMESTAMP
from mytable
TIME_STAMP NEXT_TIMESTAMP
01-JAN-22 12.13.14.002000000 01-JAN-22 12.13.14.001000000
01-JAN-22 12.13.14.001000000 null

But rather than converting to and from strings, you can add multiples of one millisecond directly:

select RTC_TIMESTAMP + (rtc_event_order_seq * interval '0.001' second) AS TIME_STAMP,
  case when Lead(RTC_TIMESTAMP, 1) over (order by RTC_TIMESTAMP) is not null then
    Lead(RTC_TIMESTAMP, 1) over (order by RTC_TIMESTAMP)
      + (Lead(rtc_event_order_seq, 1) over (order by RTC_TIMESTAMP) * interval '0.001' second)
    end AS NEXT_TIMESTAMP
from mytable
TIME_STAMP NEXT_TIMESTAMP
01-JAN-22 12.13.14.002000000 01-JAN-22 12.13.14.001000000
01-JAN-22 12.13.14.001000000 null

fiddle

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading