You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vertx Java中如何处理Oracle的RETURNING BULK COLLECT INTO子句

实现方案

你目前使用的io.vertx.ext.sql属于旧版Vertx JDBC客户端API,可通过自带的callWithParams方法注册OUT参数实现需求,具体步骤如下:

步骤1:调整PL/SQL块

原PL/SQL通过dbms_output输出的内容JDBC无法直接获取,需要修改为将返回的更新ID集合通过游标OUT参数返回,降低自定义类型的映射复杂度:

DECLARE
    TYPE updatedId IS TABLE OF Table1.col2%TYPE;
    XupdatedId updatedId;
BEGIN
    UPDATE TABLE1 SET col1 = 'OK' WHERE col2 IN ('abc','def')
    RETURNING col2 BULK COLLECT INTO XupdatedId;
    -- 绑定游标到OUT参数,返回所有更新的col2值
    OPEN ? FOR SELECT column_value FROM TABLE(XupdatedId);
END;

步骤2:Vertx代码实现

通过SQLConnection的callWithParams方法注册出参并调用PL/SQL:

import io.vertx.core.json.JsonArray;
import io.vertx.ext.sql.ResultSet;
import io.vertx.ext.sql.SQLClient;
import io.vertx.ext.sql.SQLConnection;
import oracle.jdbc.OracleTypes;

// 假设已初始化SQLClient实例sqlClient
sqlClient.getConnection(connRes -> {
    if (connRes.failed()) {
        // 自定义连接获取失败的处理逻辑
        return;
    }
    SQLConnection connection = connRes.result();
    
    String plsql = "DECLARE\n" +
            "    TYPE updatedId IS TABLE OF Table1.col2%TYPE;\n" +
            "    XupdatedId updatedId;\n" +
            "BEGIN\n" +
            "    UPDATE TABLE1 SET col1 = 'OK' WHERE col2 IN ('abc','def')\n" +
            "    RETURNING col2 BULK COLLECT INTO XupdatedId;\n" +
            "    OPEN ? FOR SELECT column_value FROM TABLE(XupdatedId);\n" +
            "END;";
    
    // 入参列表,无动态入参则为空
    JsonArray inParams = new JsonArray();
    // 注册OUT参数,类型为Oracle游标,对应数值是-10,可直接写数值避免引入Oracle驱动包常量
    JsonArray outParams = new JsonArray().add(OracleTypes.CURSOR);
    
    connection.callWithParams(plsql, inParams, outParams, callRes -> {
        if (callRes.succeeded()) {
            ResultSet resultSet = callRes.result();
            // 遍历结果集获取所有更新的col2值
            for (JsonArray row : resultSet.getResults()) {
                String updatedCol2 = row.getString(0);
                // 自定义业务逻辑处理返回的ID
                System.out.println(updatedCol2);
            }
        } else {
            // 自定义调用失败的处理逻辑
            callRes.cause().printStackTrace();
        }
        // 用完关闭连接
        connection.close();
    });
});

注意事项

  • 项目需要引入Oracle官方JDBC驱动(ojdbc8及以上版本),如果不想引入OracleTypes常量,直接将出参类型写为数值-10即可。
  • 如果IN查询的条件是动态的,不要直接拼接SQL字符串,把占位符放到inParams中传入,避免SQL注入风险。
  • 如果你使用的是Vertx 4.x及以上版本,io.vertx.ext.sql包已经被废弃,建议迁移到新版vertx-jdbc-clientAPI,对存储过程和出参的支持更完善。

内容的提问来源于stack exchange,提问作者Amit Sinha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 23:36:03