小编典典

CallableStatement + registerOutParameter +多行结果

sql

我有以下形式的SQL语句:

BEGIN\n 
UPDATE tab 
SET stuff
WHERE stuff
RETURNING intA, intB, stringC
INTO ?,?,?

我已经注册了适当的Out参数。

这是我的一些问题:我叫stmt.executeQuery()还是stmt.execute()?此外,我知道通过普通的SELECT查询,我可以遍历resultSet并填充我的对象-
Out参数的多行等效于什么?

编辑:也许我可以注册CURSOR类型的单输出参数并遍历此结果。

EDIT2:是否可能需要循环使用多个resultSet?谢谢!


阅读 220

收藏
2021-03-17

共1个答案

小编典典

我相信您可以实现所需的功能,但是您将需要处理PL / SQL数组而不是游标或结果集。下面是一个演示。

我有一个名为的表,TEST其结构如下:

SQL> desc测试;
 名称为空?类型
 ----------------------------------------- --------- ----------------

 NUMBER(38)
 B号(38)
 C号(38)

并包含以下数据:

SQL>从测试中选择*;

         美国广播公司
---------- ---------- ----------
         1 2 3
         4 5 6
         7 8 9

我需要为使用的每种列类型创建一个数组类型。在这里,我只有NUMBERs,但是如果您也有一个或多个VARCHAR2列,则也需要为它们创建一个类型。

SQL>创建类型t_integer_array作为整数表;
  2 /

类型已创建。

该表和任何必要的类型都是我们需要在数据库中设置的。完成此操作后,我们可以编写一个简短的Java类,该类执行UPDATE ... RETURNING ...,将多个值返回给Java:

import java.math.BigDecimal;
import java.util.Arrays;
import java.sql.*;
import oracle.sql.*;
import oracle.jdbc.*;

public class UpdateWithBulkReturning {
    public static void main(String[] args) throws Exception {
        Connection c = DriverManager.getConnection(
            "jdbc:oracle:thin:@localhost:1521:XE", "user", "password");

        c.setAutoCommit(false);

        /* You need BULK COLLECT in order to return multiple rows. */
        String sql = "BEGIN UPDATE test SET a = a + 10 WHERE b <> 5 " +
                     "RETURNING a, b, c BULK COLLECT INTO ?, ?, ?; END;";

        CallableStatement stmt = c.prepareCall(sql);

        /* Register the out parameters.  Note that the third parameter gives
         * the name of the corresponding array type. */
        for (int i = 1; i <= 3; ++i) {
            stmt.registerOutParameter(i, Types.ARRAY, "T_INTEGER_ARRAY");
        }

        /* Use stmt.execute(), not stmt.executeQuery(). */
        stmt.execute();

        for (int i = 1; i <= 3; ++i) {
            /* stmt.getArray(i) returns a java.sql.Array for the output parameter in
             * position i.  The getArray() method returns the data within this
             * java.sql.Array object as a Java array.  In this case, Oracle converts
             * T_INTEGER_ARRAY into a Java BigDecimal array. */
            BigDecimal[] nums = (BigDecimal[]) (stmt.getArray(i).getArray());
            System.out.println(Arrays.toString(nums));
        }

        stmt.close();
        c.rollback();
        c.close();
    }
}

运行此命令时,将得到以下输出:

C:\ Users \ Luke \ stuff> java UpdateWithBulkReturning
[11、17]
[2、8]
[3,9]

显示的输出是从柱返回的值ABC分别。由于我们将B等于5的行过滤掉,因此每一列只有两个值。

您可能需要按行分组而不是按列分组的值。换句话说,您可能希望输出包含[11, 2, 3][17, 8, 9]。如果那是您想要的,恐怕您需要自己完成这一部分。

2021-03-17