大佬教程收集整理的这篇文章主要介绍了使用 java SimpleJdbcCall 调用带有 out 参数类型“is table of varchar2”的过程 oracle,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
我创建了一个带有 2 个参数的过程 Oracle,其中一个是 out 参数类型 table OF VARCHAR2
。如何在java中调用它并获得结果?
我的测试程序创建如下:
/* creaTing package with specs */
create or replace PACKAGE PACK1 AS
TYPE name_array IS table OF VARCHAR2(50) INDEX BY BINARY_IntegeR;
PROCEDURE proc_filter_and_return_array( p_name_in IN VARCHAR2,p_name_out_array OUT name_array );
END PACK1;
/* creaTing package body with procedure */
create or replace PACKAGE BODY PACK1
as
PROCEDURE proc_filter_and_return_array(
p_name_in IN VARCHAR2,p_name_out_array OUT name_array
)IS
cursOR c_table1_SELEct is
SELEct name FROM table1_test where name like '%' || p_name_in || '%';
v_index numbER := 0;
BEGIN
FOR x IN c_table1_SELEct
LOOP
p_name_out_array( v_index ) := x.name;
v_index := v_index + 1;
END LOOP;
END proc_filter_and_return_array;
END PACK1;
DECLARE
p_name_array pack1.name_array;
BEGIN
pack1.proc_filter_and_return_array(p_name_in => 'name_to_filter',p_name_out_array => p_name_array);
DBMS_output.put_line(' number from table: ' || p_name_array(1) );
END;
但是在java中我遇到了一些错误,我正在以这种方式调用过程:
SimpleJdbcCall simpleJdbcCall = new SimpleJdbcCall(jdbcTemplatE)
.withCatalogname("PACK1")
.withProcedurename("PROC_FILTER_AND_RETURN_ARRAY")
.declareParameters( new sqlParameter("P_name_IN",Types.VARCHAR) )
.declareParameters( new sqlOutParameter("P_name_OUT_ARRAY",Types.ARRAY,"PACK1.name_ARRAY" ));
MapsqlParametersource map = new MapsqlParametersource();
map.addValue("P_name_IN","name_to_filter");
Map<String,Object> result = simpleJdbcCall.execute(map);
所以我从 java 运行得到了这个:
org.springframework.jdbc.UncategorizedsqlException: CallableStatementCallBACk; uncategorized sqlException for sql [{Call PACK1.PROC_FILTER_AND_RETURN_ARRAY(?,?)}];
sql state [99999]; error code [17074]; invalID name pattern: PACK1.name_ARRAY; nested exception is java.sql.sqlException: invalID name pattern: PACK1.name_ARRAY] with root cause
java.sql.sqlException: invalID name pattern: PACK1.name_ARRAY
at Oracle.jdbc.Oracore.OracleTypeADT.initMetadata11_2(OracleTypeADT.java:764)
at Oracle.jdbc.Oracore.OracleTypeADT.initMetadata(OracleTypeADT.java:479)
at Oracle.jdbc.Oracore.OracleTypeADT.init(OracleTypeADT.java:443)
at Oracle.sql.ArrayDescriptor.initPickler(ArrayDescriptor.java:1499)
at Oracle.sql.ArrayDescriptor.<init>(ArrayDescriptor.java:274)
at Oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:127)
at Oracle.sql.ArrayDescriptor.createDescriptor(ArrayDescriptor.java:79)
at Oracle.jdbc.driver.namedTypeAccessor.otypeFro@R_673_8156@(namedTypeAccessor.java:83)
at Oracle.jdbc.driver.TypeAccessor.initMetadata(TypeAccessor.java:76)
at Oracle.jdbc.driver.T4CCallableStatement.allocateAccessor(T4CCallableStatement.java:599)
at Oracle.jdbc.driver.OracleCallableStatement.registerOutParameterInternal(OracleCallableStatement.java:201)
at Oracle.jdbc.driver.OracleCallableStatement.registerOutParameter(OracleCallableStatement.java:240)
at Oracle.jdbc.driver.OracleCallableStatementWrapper.registerOutParameter(OracleCallableStatementWrapper.java:1243)
at com.zaxxer.hikari.pool.HikariProxyCallableStatement.registerOutParameter(HikariProxyCallableStatement.java)
at org.springframework.jdbc.core.CallableStatementCreatorFactory$CallableStatementCreatorImpl.createCallableStatement(CallableStatementCreatorFactory.java:188)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:1090)
at org.springframework.jdbc.core.JdbcTemplate.call(JdbcTemplate.java:1147)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.executeCallinternal(AbstractJdbcCall.java:412)
at org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute(AbstractJdbcCall.java:372)
at org.springframework.jdbc.core.simple.SimpleJdbcCall.execute(SimpleJdbcCall.java:198)
不幸的是,我无法更改客户端数据库中的任何内容 :( 所以我无法更改声明 TYPE name_array IS table OF VARCHAR2(50) INDEX BY BINARY_IntegeR;
并且我需要在 java、spring boot 中构建一个应用程序。有没有办法做到这一点在 Oracle 上更改程序和包。
我做错了什么?提前致谢。
其中之一是输出参数类型 TABLE OF VARCHAR2
您弄错了,其中一个是 TABLE OF VARCHAR2(50) INDEX BY BINARY_IntegeR
,它是一个关联数组,您不能使用 JDBC 映射到这种类型。
参见 this answer 或 this answer。
CREATE TYPE
定义数据类型(而不是在 pl/sqL 范围内,在包中),因为 JDBC 只能使用 SQL 定义的数据类型。INDEX BY
子句。在包外声明类型:
CREATE TYPE name_array IS TABLE OF VARCHAR2(50);
然后从包中删除关联数组声明并改用新的集合类型。之后可能会有更多的错误需要调试;但它永远不会使用关联数组工作。
不幸的是,我无法更改客户端数据库中的任何内容 :( 所以我无法更改声明 TYPE name_array IS TABLE OF VARCHAR2(50) INDEX BY BINARY_IntegeR;
并且我需要在 java、spring boot 中构建一个应用程序。有没有办法做到这一点在 Oracle 上更改程序和包。
您可以尝试通过调用匿名 pl/sqL 块(反过来调用包)来将关联数组转换为 varray
(例如 SYs.ODCIVARCHAR2LIST
)来解决此问题:>
DECLARE
v_name_assoc_array PACK1.NAME_ARRAY;
v_name_list SYs.ODCIVARCHAR2LIST := SYs.ODCIVARCHAR2LIST();
v_idx BINARY_IntegeR;
BEGIN
PACK1.proc_filter_and_return_array( :p_name_in,v_name_assoc_array );
v_idx := v_name_assoc_array.FIRST;
WHILE v_idx IS NOT NULL LOOP
v_name_list.EXTEND;
v_name_list(v_name_list.COUNT) := v_name_assoc_array(v_idX);
v_idx := v_name_assoc_array.NEXT(v_idX);
END LOOP;
:p_name_out_array := v_name_list;
END;
/
,
我是来展示代码的,因为 MTO 已经回答了我。 解决从 Java 调用匿名 pl/sqL 块并获得返回值的最佳解决方案。
我终于成功得到了下面的代码:
npm i react-currency-format
以上是大佬教程为你收集整理的使用 java SimpleJdbcCall 调用带有 out 参数类型“is table of varchar2”的过程 oracle全部内容,希望文章能够帮你解决使用 java SimpleJdbcCall 调用带有 out 参数类型“is table of varchar2”的过程 oracle所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。