Good morning dear team. I need help with the below SQL query for Oracle that is failing.
I need to use a variable for a calculation and I am obtaining the following error in the Case estatement.
“[Error] Execution (2: 1): ORA-00900: invalid SQL statement”
error : line 9, column 13, ending line 9, column 16: Found WHEN expecting FROM
DEFINE HRESP_MX = 0
SELECT
TO_CHAR( CAST ( ENTRY_TIM AS DATE ), 'DD-MM-YYYY' ) AS DATET,
TO_CHAR( CAST ( ENTRY_TIM AS DATE ), 'DD-MM-YYYY HH24' ) AS TIMET,
CRD_FIID,
MAX ( (sysdate + (RE_ENTRY_TIM - EXIT_TIM)*24*60*60 - sysdate) ) INTO HRESP_MX,
CASE WHEN ( HRESP_MX BETWEEN 0,000 and 0,200 ) THEN 'R-02'
WHEN ( HRESP_MX BETWEEN 0,201 and 0,300 ) THEN 'R0.2'
WHEN ( HRESP_MX BETWEEN 0,301 and 0,400 ) THEN 'R0.3'
WHEN ( HRESP_MX BETWEEN 0,401 and 0,500 ) THEN 'R0.4'
WHEN ( HRESP_MX BETWEEN 0,501 and 1,000 ) THEN 'R0.0'
WHEN ( HRESP_MX BETWEEN 1,001 and 1,500 ) THEN 'R1.0'
WHEN ( HRESP_MX BETWEEN 1,501 and 2,000 ) THEN 'R1.5'
WHEN ( HRESP_MX BETWEEN 2,001 and 2,500 ) THEN 'R2.0'
WHEN ( HRESP_MX BETWEEN 2,501 and 3,000 ) THEN 'R2.5'
WHEN ( HRESP_MX BETWEEN 3,001 and 3,500 ) THEN 'R3.0'
WHEN ( HRESP_MX BETWEEN 3,501 and 4,000 ) THEN 'R3.5'
WHEN ( HRESP_MX BETWEEN 4,001 and 4,500 ) THEN 'R4.0'
WHEN ( HRESP_MX BETWEEN 4,501 and 5,500 ) THEN 'R4.5'
ELSE 'R5.0' END
FROM ORACLE.File_r6
WHERE ( DAT_TIM BETWEEN '05/09/2024 05:11:00' AND '05/09/2024 05:58:59') and
( Resp_Cde <> '206' ) and
( TYP IN ( '0210', '0220' ) ) and
( RESPONDER IN ( '5' ) ) and
( TRAN_CDE_TC <> '50' )
GROUP BY
TO_CHAR( CAST ( ENTRY_TIM AS DATE ), 'DD-MM-YYYY' ),
TO_CHAR( CAST ( ENTRY_TIM AS DATE ), 'DD-MM-YYYY HH24' ),
CRD_FIID,
( (sysdate + (RE_ENTRY_TIM - EXIT_TIM)*24*60*60 - sysdate) )
ORDER by
TO_CHAR( CAST ( ENTRY_TIM AS DATE ), 'DD-MM-YYYY' ),
TO_CHAR( CAST ( ENTRY_TIM AS DATE ), 'DD-MM-YYYY HH24' ),
CRD_FIID;
It is about this line:
MAX ( (sysdate + (RE_ENTRY_TIM - EXIT_TIM)*24*60*60 - sysdate) ) INTO HRESP_MX,
----
remove INTO here, use AS
INTO
clause is used in PL/SQL, while you’re using pure SQL.
Furthermore, if I’m not wrong, you could/should remove both SYSDATE
calls as you’re basically
sysdate + something - sysdate
which leaves something only, i.e. it becomes
MAX ((RE_ENTRY_TIM - EXIT_TIM) * 24*60*60) AS HRESP_MX,
As you’re using an aggregate function, it means that all non-aggregated columns/expressions should be part of the group by
clause, which means that the whole case
expression should be moved in there.
What is dat_tim
column’s datatype? It is it a DATE
(should be), then don’t compare it to a string. Apply to_date
function with appropriate format mask.
No:
DAT_TIM BETWEEN '05/09/2024 05:11:00' AND '05/09/2024 05:58:59'
Yes:
DAT_TIM BETWEEN to_date('05/09/2024 05:11:00', 'dd/mm/yyyy hh24:mi:ss')
AND to_date('05/09/2024 05:58:59', 'dd/mm/yyyy hh24:mi:ss')
Finally, I don’t know about your database, but in mine numbers have decimal point, not comma, so maybe this
CASE WHEN ( HRESP_MX BETWEEN 0,000 and 0,200 ) THEN 'R-02' -- comma
should become
CASE WHEN ( HRESP_MX BETWEEN 0.000 and 0.200 ) THEN 'R-02' -- point
If that’s not the case in your environment, disregard this objection.
- Decimal Points should be
.
not,
. - You cannot use
HRESP_MX
in theCASE
expression when you’ve declared it in the sameSELECT
clause; instead use the calculation that underlies the alias. INTO
should beAS
.- Don’t
ORDER BY
a date string with the formatDD-MM-YYYY
, instead,ORDER BY
the underlying time. - Don’t compare dates to strings. Oracle will try an be helpful and perform an implicit string-to-date conversion but it will not work be guaranteed to work (especially if you have users in different territories around the world).
and
- If you are finding the
MAX(something)
then you probably do not also want toGROUP BY something
at the same time.
Something like this:
SELECT TO_CHAR( date_hour, 'DD-MM-YYYY' ) AS DATET,
TO_CHAR( date_hour, 'DD-MM-YYYY HH24' ) AS TIMET,
CRD_FIID,
MAX(hresp) AS hresp_mx,
CASE
WHEN MAX(hresp) BETWEEN 0.000 and 0.200 THEN 'R-02'
WHEN MAX(hresp) BETWEEN 0.201 and 0.300 THEN 'R0.2'
WHEN MAX(hresp) BETWEEN 0.301 and 0.400 THEN 'R0.3'
WHEN MAX(hresp) BETWEEN 0.401 and 0.500 THEN 'R0.4'
WHEN MAX(hresp) BETWEEN 0.501 and 1.000 THEN 'R0.0'
WHEN MAX(hresp) BETWEEN 1.001 and 1.500 THEN 'R1.0'
WHEN MAX(hresp) BETWEEN 1.501 and 2.000 THEN 'R1.5'
WHEN MAX(hresp) BETWEEN 2.001 and 2.500 THEN 'R2.0'
WHEN MAX(hresp) BETWEEN 2.501 and 3.000 THEN 'R2.5'
WHEN MAX(hresp) BETWEEN 3.001 and 3.500 THEN 'R3.0'
WHEN MAX(hresp) BETWEEN 3.501 and 4.000 THEN 'R3.5'
WHEN MAX(hresp) BETWEEN 4.001 and 4.000 THEN 'R4.0'
WHEN MAX(hresp) BETWEEN 4.501 and 5.500 THEN 'R4.5'
ELSE 'R5.0'
END AS r_value
FROM (
SELECT TRUNC(entry_tim, 'HH24') AS date_hour,
CRD_FIID,
(RE_ENTRY_TIM - EXIT_TIM)*24*60*60 AS HRESP
FROM ORACLE.File_r6
WHERE DAT_TIM BETWEEN DATE '2024-09-05' + INTERVAL '05:11:00' HOUR TO SECOND
AND DATE '2024-09-05' + INTERVAL '05:58:59' HOUR TO SECOND
AND Resp_Cde <> '206'
AND TYP IN ( '0210', '0220' )
AND RESPONDER = '5'
AND TRAN_CDE_TC <> '50'
)
GROUP BY
date_hour,
CRD_FIID
ORDER by
date_hour,
CRD_FIID;