0
@Query(value = "SELECT TRUNC(p.CREATION_DATE), SUM(p.AMOUNT)" +
            " FROM PAYMENT  p" +
            " INNER JOIN FACTOR f" +
            " ON p.PAYMENT_ID = f.FACTOR_ID" +
            " JOIN VEHICLE_GATEWAY v" +
            " ON v.FACTOR_ID = f.FACTOR_ID" +
            " WHERE :debitTypes IS null OR f.FACTOR_TYPE IN (:debitTypes)" +
            " AND p.CREATION_DATE >= :fromPaymentDate" +
            " AND p.CREATION_DATE <= :toPaymentDate" +
            " GROUP BY TRUNC(p.CREATION_DATE)" +
            " ORDER BY TRUNC(p.CREATION_DATE)", nativeQuery = true)
    Object[] getPaidDebtSummary(@Param("debitTypes") List<Integer> debitTypes,
                                @Param("fromPaymentDate") Date fromPaymentDate,
                                @Param("toPaymentDate") Date toPaymentDate);

Hi

When I run this query through spring boot app I get this error : "java.sql.SQLSyntaxErrorException: ORA-00932: inconsistent datatypes: expected NUMBER got BINARY"

but when I run it in database console in intellij it returns the result set!

Does Anyone have an idea how to solve this problem?

masoome
  • 27
  • 5

3 Answers3

0

it is because :debitTypes . instead of :debitTypes use your column name

mamJavad
  • 49
  • 8
0

The JDBC driver doesn't know how to convert a List<> into the parameter of the IN() that's why you get a BINARY as fallback. ORACLE driver doesn't support anonymous type in that context: createArrayOf of the JDBC standard is not implemented.

f.FACTOR_TYPE IN (:debitTypes) 

should be

f.FACTOR_TYPE IN ( select * from table(:debitTypes) )

and you should pass a java.sql.Array not a List, that you create with connection.createARRAY, and you need to define a TYPE in your DB, (here a TABLE OF NUMBER), to pass its name to connection.createARRAY and second argument will be an Integer[]. You may need to unwrap your java.sql.Connection into an oracle.jdbc.driver.OracleConnection.

p3consulting
  • 2,721
  • 2
  • 12
  • 10
-1

It is not possible to use :debitTypes IS null condition, it should be a column name. instead, in order to check if debitTypes list is null, do this check in a higher level (the method that calls getPaidDebtSummary), and use another query for it.

@Query(value = "SELECT TRUNC(p.CREATION_DATE), SUM(p.AMOUNT)" +
        " FROM PAYMENT  p" +
        " INNER JOIN FACTOR f" +
        " ON p.PAYMENT_ID = f.FACTOR_ID" +
        " JOIN VEHICLE_GATEWAY v" +
        " ON v.FACTOR_ID = f.FACTOR_ID" +
        " WHERE p.CREATION_DATE >= :fromPaymentDate" +
        " AND p.CREATION_DATE <= :toPaymentDate" +
        " GROUP BY TRUNC(p.CREATION_DATE)" +
        " ORDER BY TRUNC(p.CREATION_DATE)", nativeQuery = true)
Object[] getPaidDebtSummaryNoDebitTypes(@Param("fromPaymentDate") Date fromPaymentDate,
                            @Param("toPaymentDate") Date toPaymentDate);

Update: my answer was not very clear, my idea was to not to add the condition here but in a higher level, adding the condition is correct, thanks for correcting me.

Mustafa Khalil
  • 342
  • 2
  • 5
  • 1
    It is perfectly normal to use an expression like `:bindvar IS NULL` in a SQL statement. If the bound value is translated by the database adapter as an Oracle `NULL`, then `NULL IS NULL` will work as intended. – Paul W Jun 11 '23 at 13:25
  • what i need is something like this: `where (:field1 is null or table.field1 in :field1)` but when i write something like this, i get error – masoome Jun 11 '23 at 13:35