I have this LOOP inside a Procedure:
FOR foundU IN (SELECT id, uName FROM USERS)
LOOP
-- do something--
END LOOP;
My goal is to add each found User(id and uName) from the Select-Statement to a returnable "List" of these Users within the Loop. Once the Loop is finished i want to return the Result, so i can use it in Java (via CallableStatement). I know there are no Lists in SQL, and I guess a Cursor should be able to do exactly that, but i just cant figure out how I should go on.
If its hard to understand what im trying to say maybe this snippet within my LOOP can explain better:
FOR foundU IN (SELECT id, uName FROM USERS)
LOOP
-- ListofFoundUsers.add(foundU.id, foundU.uName);
END LOOP;
-- return ListofFoundUsers;
You can do this two ways.
This method returns a cursor from PL/SQL which we convert (cast) into a ResultSet and then iterate like normal. You will notice I use OracleTypes.CURSOR which makes this specific to the Oracle JDBC driver.
PL/SQL
CREATE OR REPLACE PROCEDURE ret_sys_refcursor(o_cursor OUT SYS_REFCURSOR) IS
BEGIN
OPEN o_cursor FOR
SELECT o.object_name
FROM all_objects o
WHERE o.owner = 'SYS'
AND rownum < 10;
END ret_sys_refcursor;
/
Java
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import oracle.jdbc.OracleTypes;
public class so64913833 {
public static void main(String[] args)
throws ClassNotFoundException, SQLException, IOException {
Class.forName("oracle.jdbc.driver.OracleDriver");
List<String> objects = new ArrayList<String>();
try (Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:@//<db.host.name:port/sid>", "<user>",
"<password>")) {
try (CallableStatement cs = connection
.prepareCall("{ call ret_sys_refcursor(?) }")) {
cs.registerOutParameter(1, OracleTypes.CURSOR);
cs.execute();
try (ResultSet rs = (ResultSet) cs.getObject(1)) {
while (rs.next()) {
objects.add(rs.getString("OBJECT_NAME"));
}
}
}
}
for (String object : objects) {
System.out.println(object);
}
}
}
Prints:
.xdk_version_10.2.0.3.0_production
.xdk_version_10.2.0.5.0_production
.xdk_version_11.2.0.3.0_production
.xdk_version_12.2.0.1.0_production
ACCESS$
ACLMV$
ACLMV$_BASE_VIEW
ACLMV$_MVINFO
ACLMV$_REFLOG
This method uses custom DB types. It has the limitation of needing a type that matches each possible record structure, but for basic lists of strings or numbers you can make them generic. This is documented pretty heavily here . You will notice that this example does not require the use of OracleTypes.
PL/SQL
CREATE OR REPLACE TYPE t_string_tab AS TABLE OF VARCHAR2(4000);
CREATE OR REPLACE PROCEDURE ret_string_tab(o_string_tab OUT t_string_tab) IS
BEGIN
SELECT o.object_name
BULK COLLECT
INTO o_string_tab
FROM all_objects o
WHERE o.owner = 'SYS'
AND rownum < 10;
END ret_string_tab;
/
Java
import java.io.IOException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Arrays;
import java.util.List;
public class so64913833 {
public static void main(String[] args)
throws ClassNotFoundException, SQLException, IOException {
Class.forName("oracle.jdbc.driver.OracleDriver");
List<String> objects = null;
try (Connection connection = DriverManager.getConnection(
"jdbc:oracle:thin:@//<db.host.name:port/sid>", "<user>",
"<password>")) {
try (CallableStatement cs = connection
.prepareCall("{ call ret_string_tab(?) }")) {
cs.registerOutParameter(1, Types.ARRAY, "T_STRING_TAB");
cs.execute();
objects = Arrays.asList((String[]) cs.getArray(1).getArray());
}
}
for (String object : objects) {
System.out.println(object);
}
}
}
Prints:
.xdk_version_10.2.0.3.0_production
.xdk_version_10.2.0.5.0_production
.xdk_version_11.2.0.3.0_production
.xdk_version_12.2.0.1.0_production
ACCESS$
ACLMV$
ACLMV$_BASE_VIEW
ACLMV$_MVINFO
ACLMV$_REFLOG
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.