我已经以这种方式声明了包级别类型(使用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-在oracle存储过程中传递数组:“实际上,问题是java中不可见在包中创建的任何类型。如果我在模式级别创建该类型,那么它将起作用。”
是真的吗
然后,也许我应该在架构级别定义别名?
如何?我尝试过“创建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中显示以下错误消息:Error(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代码以使用同义词:
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”
添加
我刚刚发现的一些其他信息:
有人写道:我有同样的问题。通过创建公共同义词并提供赠款来解决该问题。
如您所见,我已经做到了,但是对我来说没有运气。
添加
或...也许在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身份登录了。...在发出授权时出现错误:
错误从第1行开始-命令-向我的用户授予RM_TYPES.RECP_ARR上的授权使用类型错误报告-SQL错误:ORA-00990:权限00990缺失或无效。00000-“权限缺失或无效” *原因:
*操作:
我现在快要疯了。
您可以利用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;
这更多是一个旁注。通常,您可能应该选择乔恩·海勒(Jon Heller)建议的方法
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句