sql - PL/SQL 遍历选择结果 - 将结果连接到可返回类型
问题描述
我在一个过程中有这个循环:
FOR foundU IN (SELECT id, uName FROM USERS)
LOOP
-- do something--
END LOOP;
我的目标是将 Select-Statement 中找到的每个用户(id 和 uName)添加到循环中这些用户的可返回“列表”中。循环完成后,我想返回结果,因此我可以在 Java 中使用它(通过 CallableStatement)。我知道 SQL 中没有列表,我猜 Cursor 应该能够做到这一点,但我只是不知道我应该如何继续。
如果很难理解我想说什么,也许我的循环中的这个片段可以更好地解释:
FOR foundU IN (SELECT id, uName FROM USERS)
LOOP
-- ListofFoundUsers.add(foundU.id, foundU.uName);
END LOOP;
-- return ListofFoundUsers;
解决方案
你可以通过两种方式做到这一点。
光标
此方法从 PL/SQL 返回一个游标,我们将其转换(转换)为 ResultSet,然后像往常一样迭代。您会注意到我使用了 OracleTypes.CURSOR,这使得它特定于 Oracle JDBC 驱动程序。
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;
/
爪哇
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);
}
}
}
印刷:
.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
收藏
此方法使用自定义 DB 类型。它的局限性在于需要一种与每个可能的记录结构相匹配的类型,但对于字符串或数字的基本列表,您可以将它们设为通用。这在此处有大量记录。您会注意到此示例不需要使用 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;
/
爪哇
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);
}
}
}
印刷:
.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
推荐阅读
- laravel - 如何将 Vue 添加到现有的 Laravel 项目中?
- android - SMS检索器api android在vivo v15 pro,redmi note 4中不起作用
- java - 无法在休息控制器中重定向响应
- android - 不支持的附件
- angular - 从 http 请求数据创建表单
- angular - agm-map Angular 谷歌地图限制平移和缩放
- c# - 整个应用程序的全局静态变量/属性
- c# - 从 C# 中的串行端口接收不均匀的结果
- mysql - 从 sql 中选择时将 varchar datetime 转换为 datetime
- sql - 将列中的值分隔到 SSMS 中的不同段或列