在java中调用oracle PL/SQL函数 - 无效的列类型错误

Pra*_*nt 3 java jdbc

我想从java类调用plsql函数,但该函数(isValidPeriod)返回一个布尔数据类型,JDBC不支持它

Jun*_*san 5

由于 OCI 层的限制,JDBC 驱动程序不支持将 BOOLEAN 参数传递给 PL/SQL 存储过程。java 布尔类型与 PL/SQl 布尔类型不匹配。Oracle 文档指出 BOOLEAN 只是 PL/SQL 类型,“java.lang.Boolean”类和 PL/SQL BOOLEAN 数据类型之间没有映射。

所以恐怕你可能不得不改变你的数据库 PL/SQL 函数来返回一个整数

或者

只需创建一个包装器: function isValidPeriodInt(<params>) return integer is begin <call isValidPeriod and return 1 on true, 0 on false> end;


GWu*_*GWu 5

这个限制有一个简单的解决方法,它不需要包装函数,只需将boolean函数本身包装在一个CASE语句中,并使用Integer进行绑定:

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);
Run Code Online (Sandbox Code Playgroud)

如果您不能或不想更改功能甚至无法创建包装函数(例如在旧版DB中),则非常有用.


Jea*_*ene 5

从 JDBC-thin 驱动程序的 12.2 版本开始,对 PLSQL BOOLEAN 类型提供本机支持。

对于 IN 参数,您将执行以下操作:

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();
...
Run Code Online (Sandbox Code Playgroud)

对于 OUT 参数,您可以:

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);
Run Code Online (Sandbox Code Playgroud)