Reputation: 55
I am trying to create function of existing SELECT
query.
SELECT uta.StartDate, uta.EndDate FROM user_timesheets_absence uta
WHERE uta.UserID = 353
AND uta.Approved = 1
AND DATE '2020-06-06' BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY
When I execute this query, I get correct result in output StartDate
and EndDate
.
But problem is when I write function and try to compile I get error
Error(724,8): PL/SQL: ORA-00936: missing expression
FUNCTION GET_AVAILABE_USER_PER_DATES(p_userId IN INT,p_dateFormat IN VARCHAR2)
RETURN SYS_REFCURSOR IS
rc SYS_REFCURSOR;
BEGIN
OPEN rc FOR
SELECT uta.StartDate, uta.EndDate FROM user_timesheets_absence uta
WHERE uta.UserID = p_userId
AND uta.Approved = 1
AND DATE p_dateFormat BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY;
RETURN rc;
END GET_AVAILABE_USER_PER_DATES;
Compiler gives me error in following line
AND DATE p_dateFormat BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
I try to understand what I made wrong, where is mistake but I couldn't ? What is wrong here ? What i make wrong can someone tell me ?
UPDATE
FUNCTION ABSENCE_EXIST_FOR_DATE(p_userId IN INT,p_dateFormat IN DATE)
RETURN SYS_REFCURSOR IS
rc SYS_REFCURSOR;
BEGIN
OPEN rc FOR
SELECT uta.StartDate, uta.EndDate FROM user_timesheets_absence uta
WHERE uta.UserID = p_userId
AND uta.Approved = 1
AND p_dateFormat BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY;
RETURN rc;
END ABSENCE_EXIST_FOR_DATE;
Error gone, but unfortunetlly when I execute function I get error message
ORA-01861: literal does not match format string
01861. 00000 - "literal does not match format string"
*Cause: Literals in the input must be the same length as literals in
the format string (with the exception of leading whitespace). If the
"FX" modifier has been toggled on, the literal must match exactly,
with no extra whitespace.
*Action: Correct the format string to match the literal.
Upvotes: 0
Views: 88
Reputation: 21063
You must replace
DATE p_dateFormat
with the appropriate conversion of the VARCHAR2
parameter p_dateFormat
to the DATE type
to_char(p_dateFormat,'yyyy-mm-dd')
Adapt the the format if appropriate or use DATE
parameter in the function.
Than you would simple constraint
FUNCTION GET_AVAILABE_USER_PER_DATES(p_userId IN INT,p_dateFormat IN DATE)
...
AND p_dateFormat BETWEEN TO_DATE(uta.StartDate,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate,'YYYY-MM-DD') + INTERVAL '1' DAY
Check if the name p_dateFormat
is the best possible name for a parameter with a DATE
value (or a string with a DATE value) ...
To avoid ORA-01861: literal does not match format string
use the ON CONVERSION ERROR
clause as follows (Oracle 12 and up is required)
FUNCTION GET_AVAILABE_USER_PER_DATES(p_userId IN INT,p_dateFormat IN DATE)
...
AND p_dateFormat BETWEEN TO_DATE(uta.StartDate default null on conversion error,'YYYY-MM-DD')
AND TO_DATE(uta.EndDate default null on conversion error,'YYYY-MM-DD') + INTERVAL '1' DAY
If the column EndDate
or StartDate
contain invalid data, such as today
or 2020-99-01
the conversion will not fail with error, but returns null
, is the record will not be selected (which is probably what you want).
Upvotes: 1