Почему функция с параметром типа date возвращает неверный результат?
Чтобы сделать код более читабельным, создал функцию по преобразованию даты в формат эпохи. Однако функция возвращает некорректное значение.
Что я делаю не так?
Сама функция:
create or replace function date2epoch (datein date) return number is
epoch number;
begin
epoch := round((to_date(datein, 'yyyy-mm-dd hh24:mi:ss') -
to_date('1970-01-01', 'yyyy-mm-dd'))*24*60*60);
return epoch;
end;
Вызываю её так:
declare
dateout number;
begin
select date2epoch(to_date('2020-01-01 00:00:00', 'yyyy-mm-dd hh24:mi:ss')) into dateout
from dual;
dbms_output.put_line ('Output:'||dateout);
end;
Output:-61536240000
А то что ожидаю, можно получить выполнив тот же самый простой SQL запрос:
select round ((to_date('2020-01-01', 'yyyy-mm-dd hh24:mi:ss')
- to_date('1970-01-01', 'yyyy-mm-dd'))*24*60*60) res from dual;
RES
----------
1577836800
Свободный перевод вопроса PL/SQL function with date parameter returns wrong output от участника @honeybees
Ответы (1 шт):
что ожидаю, можно получить выполнив тот же самый простой SQL запрос
Запрос, который выполняет функция, не эквивалентен тому, который выполняется в SQL. Параметр datein уже датa, поэтому перед вызовом to_date (datein, ...), которая ожидает символьный аргумент, произойдёт преобразование в этот тип данных неявно.
Важно заметить: ни в коем случае не допускайте неявных преобразований типов данных зависящих от национальных настроек сессии.
То есть запрос, который действительно выполняет функция, выглядит так:
select round ((
to_date (to_char (date'2020-01-01', 'rr-mm-dd hh24:mi:ss'), 'yyyy-mm-dd hh24:mi:ss')
- to_date ('1970-01-01', 'yyyy-mm-dd'))*24*60*60) res from dual
/
RES
-------------
-61536240000
Исправленная функция вернёт ожидаемый результат:
create or replace function date2epoch (datein date) return number is
begin
return (round ((datein - to_date ('1970-01-01', 'yyyy-mm-dd')))*24*60*60);
end;
/
select date2epoch (date'2020-01-01') from dual
/
DATE2EPOCH(DATE'2020-01-01')
----------------------------
1577836800