calling oracle PL/SQL function in java - Invalid column type error

前端 未结 3 1208
天命终不由人
天命终不由人 2020-12-11 09:48

I want to call a plsql function from java class but that function (isValidPeriod) return a boolean datat type and JDBC doesn\'t support it

相关标签:
3条回答
  • 2020-12-11 10:16

    Due to a restriction in the OCI layer, the JDBC drivers do not support the passing of BOOLEAN parameters to PL/SQL stored procedures. The java boolean type does not match with the PL/SQl boolean type. The Oracle documentation indicates that BOOLEAN is a PL/SQL type only, and there is no mapping between the "java.lang.Boolean" class and the PL/SQL BOOLEAN data type.

    So I am afraid you may have to change your database PL/SQL function to return an integer instead

    or

    just create a wrapper: function isValidPeriodInt(<params>) return integer is begin <call isValidPeriod and return 1 on true, 0 on false> end;

    0 讨论(0)
  • 2020-12-11 10:25

    Starting in the 12.2 version of the JDBC-thin driver, there is native support for the PLSQL BOOLEAN type.

    For IN parameters you would do:

    CallableStatement cstmt = conn.prepareCall(sql);
    // Make the driver send the Java "false" boolean as a PLSQL BOOLEAN type:
    cstmt.setObject(2, false, OracleTypes.PLSQL_BOOLEAN);
    ...
    cstmt.execute();
    ...
    

    and for OUT parameters you do:

    CallableStatement cstmt = conn.prepareCall(sql);
    // The driver should expect a PLSQL BOOLEAN type for the first OUT argument
    // of the PLSQL procedure:
    cstmt.registerOutParameter(1, OracleTypes.PLSQL_BOOLEAN);
    cstmt.execute();
    ...
    boolean likeTrump = cstmt.getBoolean(1);
    
    0 讨论(0)
  • 2020-12-11 10:34

    There is a simple workaround for that restriction, which does not require a wrapper function, simply wrap the boolean function itself in a CASE statement and use an Integer for binding:

    stmt = conn.prepareCall(
              "BEGIN"
            + " ? := CASE WHEN (myBooleanFuncInOracle()) "
            + "       THEN 1 "
            + "       ELSE 0"
            + "      END;"
            + "END;");
    
    stmt.registerOutParameter(1, Types.INTEGER);
    
    // exec
    stmt.execute();
    
    // get boolean from Integer
    boolean myBool = (stmt.getInt(1) == 1);
    

    Very useful if you can't or don't want to change your function or even can't create a wrapper function, i.e. in legacy DBs.

    0 讨论(0)
提交回复
热议问题