JDBC Batch INSERT, RETURNING IDs

北慕城南 提交于 2021-01-28 09:07:02

问题


is there any way to get the values of affected rows using RETURNING INTO ? I have to insert the same rows x times and get the ids of inserted rows.

The query looks like below:

public static final String QUERY_FOR_SAVE =
        "DECLARE " +
           " resultId NUMBER ; " +
        "BEGIN " +
           " INSERT INTO x " +
           " (a, b, c, d, e, f, g, h, i, j, k, l, m)  " +
           " values (sequence.nextVal, :a, :b, :c, :d, :e, :f, :g, :h, :i, :j, :k, :l) " +
           " RETURNING a INTO :resultId;" +
        "END;";

Now i can add thise query to batch, in JAVA loop using addBatch

            IntStream.range(0, count)
                .forEach(index -> {
                    try {
                        setting parameters...
                        cs.addBatch();

                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                });
        cs.executeBatch();

Is there any way to return an array or list from batch like this ? I can execute those insert x times using just sql but in this case i also wondering how to return an array of ids.

Thanks in advance


回答1:


I'm assuming this is about Oracle. To my knowledge, this isn't possible, but you can run a bulk insertion using FORALL in your anonymous PL/SQL block, as described in this article I wrote, recently: https://blog.jooq.org/2018/05/02/how-to-run-a-bulk-insert-returning-statement-with-oracle-and-jdbc/

This is a self-contained JDBC example from the article that inserts an array of values and bulk collects the results back into the JDBC client:

try (Connection con = DriverManager.getConnection(url, props);
    Statement s = con.createStatement();

    // The statement itself is much more simple as we can
    // use OUT parameters to collect results into, so no
    // auxiliary local variables and cursors are needed
    CallableStatement c = con.prepareCall(
        "DECLARE "
      + "  v_j t_j := ?; "
      + "BEGIN "
      + "  FORALL j IN 1 .. v_j.COUNT "
      + "    INSERT INTO x (j) VALUES (v_j(j)) "
      + "    RETURNING i, j, k "
      + "    BULK COLLECT INTO ?, ?, ?; "
      + "END;")) {

    try {

        // Create the table and the auxiliary types
        s.execute(
            "CREATE TABLE x ("
          + "  i INT GENERATED ALWAYS AS IDENTITY PRIMARY KEY,"
          + "  j VARCHAR2(50),"
          + "  k DATE DEFAULT SYSDATE"
          + ")");
        s.execute("CREATE TYPE t_i AS TABLE OF NUMBER(38)");
        s.execute("CREATE TYPE t_j AS TABLE OF VARCHAR2(50)");
        s.execute("CREATE TYPE t_k AS TABLE OF DATE");

        // Bind input and output arrays
        c.setArray(1, ((OracleConnection) con).createARRAY(
            "T_J", new String[] { "a", "b", "c" })
        );
        c.registerOutParameter(2, Types.ARRAY, "T_I");
        c.registerOutParameter(3, Types.ARRAY, "T_J");
        c.registerOutParameter(4, Types.ARRAY, "T_K");

        // Execute, fetch, and display output arrays
        c.execute();
        Object[] i = (Object[]) c.getArray(2).getArray();
        Object[] j = (Object[]) c.getArray(3).getArray();
        Object[] k = (Object[]) c.getArray(4).getArray();

        System.out.println(Arrays.asList(i));
        System.out.println(Arrays.asList(j));
        System.out.println(Arrays.asList(k));
    }
    finally {
        try {
            s.execute("DROP TYPE t_i");
            s.execute("DROP TYPE t_j");
            s.execute("DROP TYPE t_k");
            s.execute("DROP TABLE x");
        }
        catch (SQLException ignore) {}
    }
}


来源:https://stackoverflow.com/questions/50393576/jdbc-batch-insert-returning-ids

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!