Thanks for the question, Ravi Chandra.
Asked: January 16, 2003 - 8:31 pm UTC
Last updated: June 02, 2004 - 8:41 am UTC
Version: 8.17
Viewed 1000+ times
You Asked
Hi,
I am facing a problem when using PL/SQL tables as out parameters in a procedure and calling the procedure from my JDBC code..
I created one object and a sql table of this object as follows
create or replace type myObjType as object
(
att1 number,
att2 varchar2(10)
);
/
create or replace type myTableType is table of myObjType;
/
I created a package in which the procedure has a table type as out parameter
the package is as follows
create or replace package testPkg
as
procedure foo( p_num in number, p_tbl in out myTableType );
end testPkg;
/
create or replace package body testPkg
as
procedure foo( p_num in number, p_tbl out myTableType )
as
begin
for i in 1 .. p_num loop
p_tbl(i).att1 := i;
p_tbl(i).att2 := 'Output ' || i;
end loop;
end;
end testPkg;
/
i am call this procedure from the JDBC code, which is as follows
import java.sql.*;
import java.io.*;
import java.util.*;
import java.math.BigDecimal;
import oracle.sql.*;
import oracle.jdbc.driver.*;
public class TestInOut extends Object
{
public static void main(String[] args) throws SQLException
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection
("jdbc:oracle:thin:@inyo:1531:YEMCSA_D","dspcs", "f0rtun3");
StructDescriptor structdesc
= StructDescriptor.createDescriptor("MYOBJTYPE", conn);
Object[] attributes = new Object[2];
attributes[0] = new BigDecimal(1);
attributes[1] = "RAV";
Object [] test = new Object[1];
test[0] = new oracle.sql.STRUCT(structdesc, conn, attributes);
ArrayDescriptor outAD
= ArrayDescriptor.createDescriptor("MYTABLETYPE", conn);
oracle.sql.ARRAY inArray = new oracle.sql.ARRAY(outAD, conn, test);
OracleCallableStatement cs
= (OracleCallableStatement)conn.prepareCall
("{CALL TESTPKG.FOO(?,?)}");
cs.setInt (1, 5);
cs.setObject(2, inArray, OracleTypes.ARRAY);
cs.registerOutParameter(2, OracleTypes.ARRAY, "MYTABLETYPE");
cs.execute();
oracle.sql.ARRAY outArray = (oracle.sql.ARRAY)cs.getARRAY(2);
ResultSet rset = outArray.getResultSet();
int i = 0;
while (rset.next())
{
System.out.println(" array e1 ( "+ i + " )" +rset.getInt(1));
System.out.println(" array e2 ( "+ i + " )" +rset.getInt(2));
System.out.println(" array e3 ( "+ i + " )" +rset.getString(3));
i++;
}
cs.close();
conn.close();
}
}
i am getting ORA-06530 error..
I have tried the same by defining the table type as follows inside the same package
type myTableType is table of myObjType index by binary_integer;
then i am getting invalid name pattern: DSPCS.MYTABLETYPE
even though i mentioned the name of table type as
TESTPKG.MYTABLETYPE
i am able to pass table type as in parameters to a procedure but am not able to retrieve as out paramenter..
i cannot user indexed plsql tables as it requires JDBC OCI driver.. our application is a web application and so we decided to use thin driver..
i am confined to use 8.1.7
pls give guide me with a the solution..
thank you
rav
and Tom said...
Well -- a WEB application, running on an app server -- would be best served with the OCI thick driver. It will perform faster, it has more options and you only need to install it on a handful of app servers.
I would only use the thin jdbc for client deployments -- thick is the only sensible one for all server installs.
Please make sure the code you POST is the code you RUN.... the spec and body above do not match
anyway - suggest you either
o use jpublisher and let it generate the java
o use "single dimension" objects instead of collections of collections of objects
o use a REF CURSOR.
I'll demonstrate a ref cursor as I believe that is by far the easiest method.
Here is the PLSQL (yours compiles but does not run)
create or replace type myObjType as object
(
att1 number,
att2 varchar2(10)
);
/
create or replace type myTableType is table of myObjType;
/
create or replace package testPkg
as
type rc is ref cursor;
procedure foo( p_num in number, p_tbl in out rc );
end testPkg;
/
create or replace package body testPkg
as
procedure foo( p_num in number, p_tbl in out rc )
as
l_tbl myTableType := myTableType();
begin
for i in 1 .. p_num loop
l_tbl.extend;
l_tbl(i) := myObjType( i, 'Output ' || i );
end loop;
open p_tbl
for
select *
from TABLE( cast(l_tbl as myTableType) );
end;
end testPkg;
/
And here is the much simplified java code:
import java.sql.*;
import java.io.*;
import java.util.*;
import java.math.BigDecimal;
import oracle.sql.*;
import oracle.jdbc.driver.*;
public class TestInOut extends Object
{
public static void main(String[] args) throws SQLException
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
Connection conn = DriverManager.getConnection
("jdbc:oracle:thin:@aria-dev:1521:ora817dev","scott", "tiger");
OracleCallableStatement cs
= (OracleCallableStatement)conn.prepareCall
("{CALL TESTPKG.FOO(?,?)}");
cs.setInt (1, 5);
cs.registerOutParameter(2, OracleTypes.CURSOR );
cs.execute();
ResultSet rset = (ResultSet)cs.getObject(2);
for( int i = 0; rset.next(); i++ )
{
System.out.println(" array e1 ( "+ i + " )" +rset.getInt(1));
System.out.println(" array e2 ( "+ i + " )" +rset.getString(2));
}
cs.close();
conn.close();
}
}
Rating
(3 ratings)
Is this answer out of date? If it is, please let us know via a Comment