views:

64

answers:

2

In the JDBC code, I have the following that is working with SQL Server:

CallableStatement stmt = connection.prepareCall("{ call getName() }");

ResultSet rs = stmt.executeQuery();

if(rs != null)
{

  while(rs.next())
  {

    //do something with rs.getString("name")

  }

}

Multiple rows are returned for the above situation.

I understand that the use of a cursor is required to loop through the table in Oracle, but is there any way to keep the above code the same and accomplish the same thing?

Sample PL/SQL code would be much appreciated.

Thanks in advance.

+2  A: 

This is straight JDBC, so it'll work with any database that has a valid JDBC driver.

It assumes, of course, that the stored proc exists in both and that you aren't using any non-standard, vendor-proprietary code in your class.

duffymo
I don't have the stored procedure in Oracle yet. Would returning a SYS_REFCURSOR with a function suffice for the above code? Sample PL/SQL code would be nice.
BeginnerAmongBeginners
A ResultSet IS a cursor. I'm sure your example is a simple one, but I didn't think the JDBC API had to know whether it was Oracle underneath. That's the whole point of JDBC. If it can't do it, I'd say either it's poorly designed or you're misunderstanding something.
duffymo
The part that is RDBMS-specific, I think, is the "call getName()". I'm guessing that in SQL Server, getName() is a function that returns multiple rows, and that as a convention it implicitly treats these as queries. Oracle does not allow this. The closest construct I know of would be "call ? = getName()", which would require more involved changes to the Java code than the other answer I submitted.
Dave Costa
Something feels wrong here. The CallableStatement should be abstracting all this for you. You should not want to return a raw cursor. You should be iterating through the ResultSet that's returned, package the results into an object or collection, and closing the ResultSet and Statement in method scope. Anything else is asking for resource leaks.
duffymo
+2  A: 

You could implement getName() as a pipelined function:

CREATE OR REPLACE name_record AS OBJECT ( name  VARCHAR2(100) );
/

CREATE OR REPLACE name_table AS TABLE OF name_record;
/

CREATE OR REPLACE FUNCTION getName RETURN name_table PIPELINED
AS
  n  name_record;
BEGIN
  -- I have no idea what you're doing here to generate your list of names, so
  -- I'll pretend it's a simple query
  FOR i IN (SELECT name FROM someTable) LOOP
    n := name_record( i.name );
    PIPE ROW(n);
  END LOOP;
END;
/

You would need to change the actual query in Java to SELECT name FROM TABLE(getName()).

Dave Costa
Is there a way to approach the PL/SQL code such that nothing needs to be changed in Java?
BeginnerAmongBeginners
I don't know of a way to write an Oracle function that will work with your existing Java code. Is the issue that you want to maintain a single Java codebase that will work with both RDBMS? If so, the only thing you need to vary between the two is a string literal, which you could store externally in a resource file, and load a different resource depending on which database you are running against.
Dave Costa