Непосредственной причиной ошибки является наличие
given_date DATE := TO_DATE('dt', 'DD-MON-YYYY');
вместо
given_date DATE := TO_DATE(dt, 'DD-MON-YYYY');
В вашей версии вы пытаетесь преобразовать строковый литерал 'dt'
в дату ; этот литерал не имеет отношения к вашему аргументу dt
.
Однако это все равно неверно, поскольку dt
уже объявлен как тип данных даты. Если вы это сделаете, то вы действительно делаете:
given_date DATE := TO_DATE(TO_CHAR(dt), 'DD-MON-YYYY');
, который будет использовать ваш текущий сеанс NLS_DATE_FORMAT
для преобразования даты в строку; если это тоже не «ДД-МЕС-ГГГГ» (или что-то достаточно близкое, чтобы Oracle обманул ), вы все равно получите ошибку или, что еще хуже, неправильное преобразование и недопустимые результаты, которые вы может не заметить.
Так что удалите это избыточное и опасное преобразование:
CREATE OR REPLACE PROCEDURE get_days(dt date)
IS
BEGIN
DBMS_OUTPUT.PUT_LINE ('The day of the given date is ' || TO_CHAR(dt, 'FMDAY') || '.');
DBMS_OUTPUT.PUT_LINE ('Execution done successfully.');
END get_days;
/
Конечно, вы можете присвоить название дня строковой переменной, если хотите. Я использовал модификатор формата FM
, чтобы не допустить, чтобы он дополнял название дня справа, поэтому вам не нужно обрезать его - точка просто нужна, чтобы продемонстрировать, что работает. Если вы хотите, чтобы название дня было в смешанном регистре, вы можете использовать 'FMDay'
вместо 'FMDAY'
.
Вы всегда должны передавать дату, а не строку:
set serveroutput on;
BEGIN
get_days(date '2012-12-12');
get_days(TO_DATE( '01/01/2018', 'MM/DD/YYYY' ));
END;
/
The day of the given date is WEDNESDAY.
Execution done successfully.
The day of the given date is MONDAY.
Execution done successfully.
PL/SQL procedure successfully completed.
dt можно передавать в любом формате. Я просто конвертирую его в формат ДД-ММ-ГГГГ и сохраняю в given_date
Дата не имеет формата; у него есть внутреннее представление, о котором вам очень редко нужно знать или о котором нужно заботиться. Когда вы запрашиваете значение даты без явного преобразования его в строку, ваш клиент преобразует его в удобочитаемую форму, обычно используя NLS_DATE_FORMAT
, чтобы решить, в каком формате его отображать. Итак, dt
не имеет формата, и даже если вызывающий выполняет вызов со строкой (как в ваших первых двух примерах), они будут неявно преобразованы в дату - если это возможно - перед вызовом; процедура никогда не увидит эти строки, она увидит только преобразованное значение даты.