Oracle JDBC / PL SQL / TYPE /包级别/无效的名称模式

时间:2014-12-19 06:46:23

标签: java oracle stored-procedures jdbc plsql

我已经用这种方式声明了包级别类型(使用Oracle XE 11):

create or replace PACKAGE RM_TYPES
AS
    TYPE RECPPART_ARR IS TABLE OF RM_RECEPCIONPARTIDAS%ROWTYPE;
END RM_TYPES;

我有这样的SP:

create or replace PROCEDURE "RM_TRY_B" (partidas OUT RM_TYPES.RECPPART_ARR) as 
begin
  SELECT * BULK COLLECT INTO partidas FROM rm_recepcionpartidas;
end;

我有这样的java代码:

CallableStatement cstmt = conn.prepareCall("{call RM_TRY_B(?)}");
cstmt.registerOutParameter(1, OracleTypes.ARRAY, "RM_TYPES.RECPPART_ARR");
cstmt.execute();
Array a = cstmt.getArray(1);

它给了我一个例外:

Exception in thread "main" java.sql.SQLException: invalid name pattern: RM_TYPES.RECPPART_ARR

我已经通过向oracle发出此命令来授予对我的用户的访问权限:

GRANT EXECUTE ON RM_TYPES TO myuser;

我使用它作为参考:https://docs.oracle.com/database/121/JJDBC/apxref.htm#JJDBC28913(命名为:使用%ROWTYPE属性为每行创建Java级别对象

我哪里做错了?


我也尝试在我的java代码中传递此名称:" RECPPART_ARR"或" MYSCHEMA.RM_TYPES.RECPPART_ARR"它们都不起作用。

然后我读到有人在stackoverflow上说这个:java - passing array in oracle stored procedure:"实际上问题是java中看不到包中创建的任何类型。如果我在模式级别创建类型,那么它的工作原理。 "

是真的吗?

那么也许我应该在架构级别定义一个别名?

如何?我尝试了#34;创建SYNONYM":

CREATE PUBLIC SYNONYM RECPPART_ARRAY FOR RM_TYPES.RECPPART_ARR;

然后(试图修改我的SP):

create or replace PROCEDURE "RM_TRY_B" (partidas OUT RECPPART_ARRAY) as 
begin
  SELECT * BULK COLLECT INTO partidas FROM rm_recepcionpartidas;
end;

但这次这个SP无法编译,我的SQLDeveloper中出现此错误消息:错误(1,36):PLS-00905:对象MYSCHEMA.RECPPART_ARRAY无效。

然后我尝试使用我之前的sp:

定义
create or replace PROCEDURE "RM_TRY_B" (partidas OUT RM_TYPES.RECPPART_ARR) as 
begin
  SELECT * BULK COLLECT INTO partidas FROM rm_recepcionpartidas;
end;

修改我的Java代码以改为使用synomim:

CallableStatement cstmt = conn.prepareCall("{call RM_TRY_B(?)}");
cstmt.registerOutParameter(1, OracleTypes.ARRAY, "RECPPART_ARRAY");
cstmt.execute();
Array a = cstmt.getArray(1);

仍然是异常,带有消息:无法构造描述符:无法解析类型:" MYSCHEMA.RECPPART_ARRAY"


ADDITION

我刚发现的其他一些信息:

http://oracle.developer-works.com/article/5227493/%22invalid+name+pattern%22++when+trying+to+user+packaged+TYPE

有人写道:我有同样的问题。管理通过创建公共同义词和赠款来解决它。

如你所见,我已经这样做了,但对我来说没有运气。


ADDITION

或者......在oracle中可能是这样的(在阅读之后:http://docs.oracle.com/javadb/10.10.1.2/ref/rrefsqljgrant.html):

create or replace PACKAGE RM_TYPES
AS
  TYPE RECPPART_ARR IS TABLE OF RM_RECEPCIONPARTIDAS%ROWTYPE;
END RM_TYPES;

sqlplus (logged in as sys as SYSDBA)> GRANT USAGE ON TYPE RM_TYPES.RECPPART_ARR TO myuser;

CREATE PUBLIC SYNONYM RECPPART_ARRAY FOR RM_TYPES.RECPPART_ARR;

create or replace PROCEDURE "RM_TRY_B" (partidas OUT RM_TYPES.RECPPART_ARR) as 
begin
  SELECT * BULK COLLECT INTO partidas FROM rm_recepcionpartidas;
end;

...

我试过了......,甚至使用用户" sys"作为SYSDBA ....我在发出grant时遇到错误:

从命令行中的第1行开始出错 - 在RM_TYPES.RECP_ARR上向myuser授予使用类型 错误报告 - SQL错误:ORA-00990:缺少或无效的权限 00990. 00000 - "缺少或无效的特权" *原因:
*操作:

我现在已经没想完了。

2 个答案:

答案 0 :(得分:2)

JDBC Support for PL/SQL Data Types as Parameters是Oracle 12c的新功能。

PL / SQL类型看起来像常规类型;它们可以在SQL和其他上下文中使用,它们具有TYPE_OID和TYPECODE,并且它们具有数据字典视图(DBA_PLSQL_TYPES)。一个奇怪的区别是PL / SQL类型没有出现在DBA_OBJECTS中。

在旧版本中,您必须创建一个TYPE作为独立对象,以便在PL / SQL之外使用它。像这样的代码可以创建对象:

CREATE OR REPLACE TYPE RECPPART_REC IS OBJECT
(
    --list RM_RECEPCIONPARTIDAS columns here.  %ROWTYPE is not available in SQL.
);

CREATE OR REPLACE RECPPART_ARR IS TABLE OF RECPPART_REC;

答案 1 :(得分:1)

您可以在PL / SQL中使用一个鲜为人知的功能:PIPELINED函数。一个例子:

create table tab (
  id number(7)
);
/

insert into tab values (1);
insert into tab values (2);

create or replace package pkg
as
  type typ is table of tab%rowtype;
end pkg;
/

create or replace procedure proc (param out pkg.typ) as 
begin
  select * bulk collect into param from tab;
end;
/

create or replace function func return pkg.typ pipelined as
begin
  for rec in (select * from tab) loop
    pipe row(rec);
  end loop;
end;
/

select * from table(func);

以上将产生:

ID
--
1
2

因此,您也可以轻松地从JDBC中实现表类型。

原因是每个流水线函数都隐式创建一个与PL / SQL表类型相同类型的顶级SQL类型。在上面的例子中:

create or replace type SYS_PLSQL_29848_13_1 as object (ID NUMBER(7));
create or replace type SYS_PLSQL_29753_9_1 as table of SYS_PLSQL_29848_13_1;

这更像是一个侧面说明。一般来说,您可能更喜欢the approach suggested by Jon Heller