2012-03-09 78 views
1

我有一个带有以下签名的PLSQL代码。如何从PLSQL获取表用户定义类型作为出参数?

procedure getall(
    p_id    in number, 
    p_code    in varchar2, 
    x_result   out tt_objs); 

type rt_obj is record(
    val1    mytable.attr1%type 
    val2    mytable.attr2%type 
    val3    mytable.attr2%type 
); 

type tt_objs is table of rt_obj index by binary_integer; 

应该是什么的Java代码可以调用这个程序,阅读x_result

回答

1

也许this可能是你在找什么。

这应该是一个有趣的现象:

//oracle.sql.ARRAY we will use as out parameter from the package 
//and will store pl/sql table 
ARRAY message_display = null; 

//ArrayList to store object of type struct 
ArrayList arow= new ArrayList(); 

//StructDescriptor >> use to describe pl/sql object 
//type in java. 
StructDescriptor voRowStruct = null; 

//ArrayDescriptor >> Use to describe pl/sql table 
//as Array of objects in java 
ArrayDescriptor arrydesc = null; 

//Input array to pl/sql procedure 
ARRAY p_message_list = null; 

//Oracle callable statement used to execute procedure 
OracleCallableStatement cStmt=null; 

try 
{ 
//initializing object types in java. 
voRowStruct = StructDescriptor.createDescriptor("RECTYPE",conn); 
arrydesc = ArrayDescriptor.createDescriptor("RECTAB",conn); 
} 

catch (Exception e) 
{ 
throw OAException.wrapperException(e); 
} 

for(XXVORowImpl row = (XXVORowImpl)XXVO.first(); 
row!=null; 
row = (XXVORowImpl)XXVO.next()) 
{ 
//We have made this method to create struct arraylist 
// from which we will make ARRAY 
//the reason being in java ARRAY length cannot be dynamic 
//see the method defination below. 
populateObjectArraylist(row,voRowStruct,arow); 
} 

//make array from arraylist 
STRUCT [] obRows= new STRUCT[arow.size()]; 
for(int i=0;i < arow.size();i++) 
{ 
obRows[i]=(STRUCT)arow.get(i); 
} 

try 
{ 
p_message_list = new ARRAY(arrydesc,conn,obRows); 
} 
catch (Exception e) 
{ 
throw OAException.wrapperException(e); 
} 

//jdbc code to execute pl/sql procedure 
try 
{ 
cStmt 
=(OracleCallableStatement)conn.prepareCall("{CALL ioStructArray.testproc(:1,:2)}"); 
cStmt.setArray(1,p_message_list); 
cStmt.registerOutParameter(2,OracleTypes.ARRAY,"RECTAB"); 
cStmt.execute(); 

//getting Array back 
message_display = cStmt.getARRAY(2); 
//Getting sql data types in oracle.sql.datum array 
//which will typecast the object types 
Datum[] arrMessage = message_display.getOracleArray(); 

//getting data and printing it 
for (int i = 0; i < arrMessage.length; i++) 
{ 
oracle.sql.STRUCT os = (oracle.sql.STRUCT)arrMessage[i]; 
Object[] a = os.getAttributes(); 
System.out.println("a [0 ] >>attribute1=" + a[0]); 
System.out.println("a [1 ] >>attribute2=" + a[1]); 
System.out.println("a [2 ] >>attribute3=" + a[2]); 
+1

如果'rectype'和'rectab'都在一个包中。我如何访问它们? – AppleGrew 2012-03-09 09:03:24

+0

你有考虑过使用游标吗? http://www.oracle-base.com/articles/misc/UsingRefCursorsToReturnRecordsets.php – Eggi 2012-03-09 09:08:41

+0

我不知道该怎么做。此外,它所定义的包不属于我。所以,我不能修改这个包。 – AppleGrew 2012-03-09 09:14:50

1

是的,它直接是不可能的。你可以是

  • 创建一个与PLSQL记录具有相同结构的公共类型,并遵循Eggi的建议。类似的方法使用Oracle JPublisher。 JPublisher可以帮助您自动执行此过程。
  • 或者您可以使用匿名PLSQL块创建或读取PLSQL记录。我们正在考虑创建一个库在我们公司自动执行。
  • 或者你可以创建一个包装函数来将记录包装成XML(在Java和PLSQL中)。然后将XML作为Xmltype或CLOB在DB和Java之间传递。我们已经有一些复杂结构的解决方案。这很乏味,会减慢一点处理速度,但它起作用。
相关问题