当前位置: 首页 > 知识库问答 >
问题:

使用java SimpleJdbcCall调用out参数类型为“is table of Varchar2”的过程oracle

宦琪
2023-03-14

我创建了一个有两个参数的过程oracle,其中一个是out参数类型表的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;
    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);
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.otypeFromName(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)

不幸的是,我无法更改客户机数据库中的任何内容:(因此,我无法更改声明类型name_array是binary_integer的VARCHAR2(50)索引表;,我需要用java构建一个应用程序,spring boot。

我做错了什么?提前谢了。

共有1个答案

罗法
2023-03-14

其中之一是varchar2的out参数类型

您搞错了,其中一个是由binary_integer索引的VARCHAR2(50)的表,它是一个关联数组,您不能使用JDBC映射到这种类型。

看到这个答案或者这个答案。

    null
CREATE TYPE name_array IS TABLE OF VARCHAR2(50);

您可以尝试通过调用匿名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;
/

 类似资料:
  • 问题内容: 我已经使用PDO一段时间了,并且正在重构一个项目,以便它使用存储的proc而不是内联SQL。我收到一个我无法解释的错误。我正在使用PHP版本5.3.5和MySQL版本5.0.7。 我只是想获得一个带有输出的基本存储过程。这是存储的过程: 这是我用来调用proc的代码,$ db是PDO的一个实例: 简单吧?但是,它导致以下错误: 如果我直接这样调用proc: 它按预期工作,这使我相信PH

  • 我通过Hibernate调用了一个带有OUT参数的存储过程,得到了以下错误: 我的存储过程: Hibernate映射: 我按如下方式调用了存储过程: 有人能解释一下这段代码有什么问题吗?

  • 我需要对一个参数为PL/SQL表的过程进行JDBC调用。我正在尝试结构对象。但是我没有做正确的事情。我得到错误: ORA-04043:对象“斯科特”。“对象列表结构”不存在。 以下是代码片段: 参数“?”对于本程序,类型为: 我们非常感谢任何能让我们成功的见解谢谢

  • 问题内容: 我的包体内有一个proc: 我在包装规格中公开了这一点。 如何在PL SQL Developer(或类似版本)的新SQL窗口中执行此过程? 问题答案: 您可以相对轻松地执行该过程 当然,这只是将游标返回到调用应用程序。它不执行任何操作来从游标中获取数据,对该数据执行任何操作或关闭游标。假设您的目标是向其中写入一些数据(有时对于原型设计很有用,但生产代码不应该依赖该数据),则可以执行以下

  • 我在HANA数据库中创建了这个存储过程,它使用两个参数,一个是表类型,另一个是。 现在我想在Java中调用这个过程,我写了这样的东西。 有人能告诉我在调用此存储过程时,如何将对象作为参数中的表实体传递吗?

  • 问题内容: 听起来很荒谬,但是我无法修复这段代码: 无论我如何写闭包,我总是会遇到此错误: 无法使用类型为’ ‘ 的参数列表调用’filter ‘ 定义如下: 并且是Swift类(不继承自NSObject) 我在许多其他地方都使用了几乎相同的产品,而没有出现问题。有什么建议? 问题答案: 如果您不符合以下条件,则会收到该错误: