Search code examples
oracle-sqldevelopersqlplusbind-variables

Passing Bind Variable in case statements in Oracle query


I want to pass Bind Variable (a Date) in a Case statement in order to achieve the following: When User inputs a date and if that Date is falling on Monday, then the Case statement should fetch the value of Friday (meaning it should bypass the weekends and look for the values of a previous working day)

I tried to use the following query which works well when I use 'sysdate'

Select * from table_name
Where tradedate = trunc (sysdate - case to_char(sysdate, 'Dy') 
when 'Mon' then 3 else 1 end);

but when I replace 'sysdate' with a Bind Variables, it gives me an error like:

tradedate = trunc (:sysdate1 - case to_char(:sysdate2, 'Dy') 
when 'Mon' then 3 else 1 end);

ORA-00932: inconsistent datatypes: expected DATE got NUMBER 00932. 00000 - "inconsistent datatypes: expected %s got %s"

Can't we use Bind Variables in Case statement in oracle queries? If so, Can someone please give me any alternate solution to my problem stated above?

Any help would be really appreciated.

Below is the complete code:

select * from (
SELECT
    S."TRADEDATE",S."ACCOUNT_NAME",S."BOOKING_AMOUNT",S."ACCOUNT_NUMBER",(CASE WHEN BOOKING_AMOUNT <0 THEN S."CREDIT" ELSE S."DEBIT" END) AS "DEBIT" , (CASE WHEN BOOKING_AMOUNT <0 THEN S."DEBIT"  ELSE S."CREDIT" END) AS "CREDIT",
    U.VALUE_DT , U.AC_NO , NVL(U.BOOKED_AMOUNT ,0) BOOKED_AMOUNT
FROM
    SXB S
    FULL OUTER JOIN UBS U ON
        S.ACCOUNT_NUMBER = U.AC_NO
    AND
        S.TRADEDATE = U.VALUE_DT
       
        UNION ALL
SELECT
BOOKING_DATE TRADEDATE,
'SAXO RECON' ACCOUNT_NAME,
SUM((Case when DR_CR_INDICATOR = 'D' then AMOUNT*-1 when DR_CR_INDICATOR = 'C' then AMOUNT end)) BOOKING_AMOUNT,
EXTERNAL_ACCOUNT ACCOUNT_NUMBER,
'Matched - ' ||A.MATCH_INDICATOR AS DEBIT,
NULL AS CREDIT,
VALUE_DATE VALUE_DT,
NULL AS AC_NO,
0 AS BOOKED_AMOUNT
FROM
    FCUBS.RETB_EXTERNAL_ENTRY A
WHERE A.EXTERNAL_ENTITY = 'SAXODKKKXXX'
      AND A.EXTERNAL_ACCOUNT = '78600/COMMEUR'
    group by
    BOOKING_DATE ,
EXTERNAL_ACCOUNT ,
VALUE_DATE,
MATCH_INDICATOR

order by tradedate, account_name)
where tradedate = trunc (:sysdate1 - case to_char(:sysdate2, 'Dy') when 'Mon' then 3 else 1 end);

Solution

  • SYSDATE is a date datatype so oracle will always treat it as a DATE datatype. For a bind variable I'd do an explicit conversion using TO_DATE(:bind_var, 'FORMAT_MASK'). For example:

    select 
      case TO_CHAR(TO_DATE(:sysdate2,'DD-MON-YYYY'), 'Dy') when 'Mon'
         then 3 
         else 1 
      end from dual