Oracle 11g
Problem
- You need to write a PL/SQL function that returns a collection of records
- The function will be used by
- other PL/SQL programs
- SQL queries
- a Java service
This can be a tough set of requirements to meet, especially when the records that you are returning don't map to a row from an existing table or view.
Solution
Write two flavors of the function: one that returns a nested table object and a second that calls the first function and returns a SYS_REFCURSOR.
Step 1: Create an object type that represents the record you will return.
CREATE OR REPLACE TYPE my_obj IS OBJECT ( obj_id INTEGER, status VARCHAR2(30), active VARCHAR2(1) ) /
Step 2: Create a nested table type based on your new object.
CREATE OR REPLACE TYPE my_obj_tab IS TABLE OF my_obj /
Step 3: Create the package that contains the two flavors of the function.
CREATE OR REPLACE PACKAGE mypack IS
FUNCTION f_get_objects RETURN my_obj_tab; -- use this for PL/SQL and SQL
FUNCTION f_get_objects_cur RETURN SYS_REFCURSOR; -- use this one for Java
END mypack;
/
CREATE OR REPLACE PACKAGE BODY mypack IS
FUNCTION f_get_objects RETURN my_obj_tab IS
BEGIN
RETURN my_obj_tab(my_obj(obj_id => 1,
status => 'whatever',
active => 'Y'),
my_obj(obj_id => 2,
status => 'whatever again',
active => 'Y'));
END f_get_objects;
FUNCTION f_get_objects_cur RETURN SYS_REFCURSOR IS
l_cursor SYS_REFCURSOR;
BEGIN
OPEN l_cursor FOR
SELECT *
FROM TABLE(f_get_objects);
RETURN l_cursor;
END f_get_objects_cur;
END mypack;
/
Using the function in PL/SQL
DECLARE l_objects my_obj_tab; BEGIN l_objects := mypack.f_get_objects; dbms_output.put_line(l_objects(1).status); END / whatever PL/SQL procedure successfully completedUsing the function in SQL
SELECT * FROM TABLE(mypack.f_get_objects) ORDER BY status;Using the function in JAVA
...
OracleCallableStatement cs = (OracleCallableStatement)
conn.prepareCall("{? = call mypack.f_get_objects_cur() }"); //no params
cs.registerOutParameter(1, OracleTypes.CURSOR);
cs.execute();
OracleResultSet rs = (OracleResultSet) cs.getCursor(1);
while (rs.next()){
System.out.println("ID:" + rs.getInt("obj_id") + " STATUS:"
+ rs.getString("status"));
}
...
No comments:
Post a Comment