我需要使用一个带有VARCHAR2和OUT参数的IN参数作为BOOLEAN数据类型来调用Oracle过程。
以下是使用SimpleJdbcCall
的代码SimpleJdbcCall jdbcCall = new SimpleJdbcCall(getTemplate())
.withCatalogName("package_name")
.withProcedureName("proc_name")
.withoutProcedureColumnMetaDataAccess()
.declareParameters(
new SqlParameter ("userName", Types.VARCHAR),
new SqlOutParameter("status", Types.BOOLEAN)
);
Map<String, Object> inParams = new HashMap<String, Object>();
inParams .put("userName", userInput);
Map<String, Object> outputValue= jdbcCall.execute(inParams);
异常:CallableStatementCallback;未分类的SQLException for SQL [{call PACKAGE_NAME.PROC_NAME(?,?)}]; SQL状态[99999]; 错误代码[17004];列类型无效:16;嵌套异常是 java.sql.SQLException:列类型无效:16
进行研究后发现“ JDBC驱动程序不支持将布尔参数传递给PL / SQL存储过程”
建议使用第二个PL / SQL过程包装PL / SQL过程。主要问题是我在数据库中限制写入访问,因为它是客户端数据。请帮我解决这个问题。
我提到的一些链接
答案 0 :(得分:3)
我通过编写一个包装程序来处理实际过程的结果并将结果作为varchar数据类型发回来修复了这个问题。 如果您有任何人认为这是错误的方法,或者您有任何简单的方法来解决这个问题,请分享您的意见。
以下是程序:
DECLARE
userName VARCHAR2(13);
status BOOLEAN;
result VARCHAR2(13);
BEGIN
userName := ?;
status := NULL;
package_name.proc_name ( userName, status);
BEGIN
IF status THEN result := 'Yes';
ELSIF NOT status THEN result := 'No';
ELSE result := 'NULL';
END IF;
END;
COMMIT;
? := result;
END ;
我还使用CallableStatement来处理它,而不是simpleJdbcCall。请参阅以下内容:
try{
String wrapperProc= "DECLARE userName VARCHAR2(13); status BOOLEAN; result VARCHAR2(13); BEGIN userName := ?; status := NULL; "+
"package_name.proc_name ( userName, status ); BEGIN IF status THEN result := 'Yes'; ELSIF NOT status THEN " +
"result := 'No'; ELSE result := 'NULL'; END IF; END; COMMIT; ? := result;END ;";
CallableStatement proc_stmt= null;
proc_stmt = getTemplate().getDataSource().getConnection().prepareCall(wrapperProc);
proc_stmt.setString(1, "userName");
proc_stmt.registerOutParameter(2, Types.VARCHAR);
proc_stmt.execute();
System.out.println("Final Result : "+proc_stmt.getString(2));
} catch(SQLException e){
System.out.println("SQL Exception : "+e.getMessage());
e.printStackTrace();
} catch (Exception e) {
System.out.println("Exception : "+e.getMessage());
e.printStackTrace();
}
~~素里亚
答案 1 :(得分:3)
来自官方的Oracle JDBC documentation:
Oracle JDBC驱动程序支持调用是不可行的 PL / SQL RECORD,BOOLEAN或表的参数或返回值 非标量元素类型。 [...]作为PL / SQL RECORD的解决方法, BOOLEAN或非标量表类型创建容器过程 将数据作为JDBC支持的类型处理。例如,包装一个 使用PL / SQL布尔值的存储过程,创建一个存储过程 从JDBC获取一个字符或数字并将其传递给 原始过程为BOOLEAN,或者对于输出参数,接受a 来自原始过程的BOOLEAN参数并将其作为CHAR传递 或NUMBER到JDBC。同样,要包装使用的存储过程 PL / SQL记录,创建一个处理其中记录的存储过程 单个组件,例如CHAR和NUMBER,或结构化的组件 对象类型。
这正是您在答案中所做的,但我想添加文档作为参考。