Java 从存储过程(oracle DB)检索数组时出错

Java 从存储过程(oracle DB)检索数组时出错,java,oracle,plsql,Java,Oracle,Plsql,我已经在数据库中创建了第一个类型 CREATE or replace TYPE notif_array AS table OF VARCHAR2(10); 然后我创建了存储过程 CREATE OR REPLACE PROCEDURE get_notification_id(personrole in varchar2,personid out notif_array) is begin select person_id bulk collect into personid from ex

我已经在数据库中创建了第一个类型

CREATE or replace  TYPE notif_array AS table OF VARCHAR2(10);
然后我创建了存储过程

CREATE OR REPLACE PROCEDURE get_notification_id(personrole in varchar2,personid out notif_array)
is
begin
select person_id bulk collect  into personid from  exp_role_person_mapping where person_role=personrole;
exception when others then
personid:=null;
end;
我的java代码

        CallableStatement cs = db.createCallableStatement("begin get_next_level_dtls(?,?);end;", 0);
        cs.setObject(1,historyRow.getAttribute("ToRole").toString());
        cs.registerOutParameter(2, OracleTypes.ARRAY,"notif_array");
        cs.execute();
        String[] PersonIds = (cs.getArray(2)!=null && cs.getArray(2).getArray()!=null) ?
            (String[])cs.getArray(2).getArray():
            null;
它给出了cs.registerOutParameter(2,OracleTypes.ARRAY,“notif_数组”)的错误;上面说


您需要使用与数据字典中显示的对象名称相同的大小写。使用创建时,它在字典中的名称为
NOTIF\u ARRAY
not
NOTIF\u ARRAY
。您可以通过以下方式进行验证:

select owner, object_name
from all_objects where object_type = 'TYPE'
and lower(object_name) = 'notif_array';
因此,您需要使用:

cs.registerOutParameter(2, OracleTypes.ARRAY, "NOTIF_ARRAY");
(顺便说一句,您得到的错误来自瘦驱动程序;使用OCI驱动程序,您得到了一个稍微有用的ORA-04043对象不存在错误)

另外,您正在调用的过程是
get\u next\u level\u dtls
,而不是显示定义的过程,
get\u notification\u id
。如果两个过程具有相同的参数类型,这些参数可能有效,但不能给出预期的结果;但是如果
get\u next\u level\u dtls
具有不同的参数类型,您将得到PLS-00306错误

除非您在发布问题时不一致地更改了姓名(这看起来不太可能),否则请将您的呼叫更改为正确的程序:

CallableStatement cs = db.createCallableStatement("begin get_notification_id(?,?);end;", 0);

我假设
db
是您自己的连接管理类包装器。

您需要使用与数据字典中显示的对象名称相同的大小写。使用创建时,它在字典中的名称为
NOTIF\u ARRAY
not
NOTIF\u ARRAY
。您可以通过以下方式进行验证:

select owner, object_name
from all_objects where object_type = 'TYPE'
and lower(object_name) = 'notif_array';
因此,您需要使用:

cs.registerOutParameter(2, OracleTypes.ARRAY, "NOTIF_ARRAY");
(顺便说一句,您得到的错误来自瘦驱动程序;使用OCI驱动程序,您得到了一个稍微有用的ORA-04043对象不存在错误)

另外,您正在调用的过程是
get\u next\u level\u dtls
,而不是显示定义的过程,
get\u notification\u id
。如果两个过程具有相同的参数类型,这些参数可能有效,但不能给出预期的结果;但是如果
get\u next\u level\u dtls
具有不同的参数类型,您将得到PLS-00306错误

除非您在发布问题时不一致地更改了姓名(这看起来不太可能),否则请将您的呼叫更改为正确的程序:

CallableStatement cs = db.createCallableStatement("begin get_notification_id(?,?);end;", 0);

我假设
db
是您自己的连接管理类包装器。

您可以添加完整的stacktrace吗?@Jens这样做了。我还使用了java.sql.Types.Array而不是OracleTypes.Array。但是你调用的过程仍然不是你给我们展示的那个过程,但是可能两者都有相同的参数类型?还有,为什么要使用
setObject()
而不是
setString()
?现在我使用的是@AlexPoole。现在我又遇到一个错误,你能添加完整的stacktrace吗?@Jens这样做了。我还使用了java.sql.Types.Array而不是OracleTypes.Array。但是你调用的过程仍然不是你给我们展示的那个过程,但是可能两者都有相同的参数类型?还有,为什么要使用
setObject()
而不是
setString()
?现在我使用的是@AlexPoole。现在我又犯了一个错误