DB2 存储过程使用 Java 应用程序中的列表数组运行多个插入和更新 SQL 语句

问题描述 投票:0回答:1

我想使用 DB2 存储过程从我的 Java 应用程序运行多插入和更新 SQL 语句。我准备了以下包含错误的程序。

在这个实现中,我首先要创建一个临时表来存储SQL语句。然后使用循环将 SQL 语句插入到使用准备好的语句的临时表中。最后,我们以批处理模式执行 SQL 语句。

要从我的 Java 应用程序调用此存储过程,我想将 SQL 语句列表作为字符串列表数组传递。

这是我的程序:

CREATE OR REPLACE PROCEDURE multiInsertAndUpdate(IN sqlStatements VARCHAR(2000) ARRAY)
BEGIN
DECLARE batchStmt VARCHAR(2000);
DECLARE i INTEGER DEFAULT 0;
-- Create a temporary table to store the SQL statements
CREATE TEMPORARY TABLE temp_sql_statements (
id INTEGER GENERATED ALWAYS AS IDENTITY,
statement VARCHAR(2000)
);
-- Insert the SQL statements into the temporary table using a prepared statement
DECLARE insertStmt STATEMENT;
SET insertStmt = 'INSERT INTO temp_sql_statements(statement) VALUES(?)';
FOR i IN 1..CARDINALITY(sqlStatements) DO
   EXECUTE IMMEDIATE insertStmt USING sqlStatements[i];
END FOR;
-- Execute the SQL statements in batches of 1000
SET i = 0;
WHILE i >= 0 DO
DECLARE stmtCursor CURSOR WITH HOLD FOR
SELECT statement FROM temp_sql_statements ORDER BY id FOR UPDATE SKIP LOCKED FETCH FIRST 1000 ROWS ONLY;
OPEN stmtCursor;
FETCH FROM stmtCursor INTO batchStmt;
IF batchStmt IS NOT NULL THEN
  DECLARE batchStmts VARCHAR(20000);
  SET batchStmts = batchStmt;
  SET i = i + 1;
  WHILE FETCH FROM stmtCursor INTO batchStmt DO
    SET batchStmts = batchStmts || batchStmt || ';';
    SET i = i + 1;
    IF i % 1000 = 0 THEN
      EXECUTE IMMEDIATE batchStmts;
      SET batchStmts = '';
    END IF;
  END WHILE;
  IF batchStmts <> '' THEN
    EXECUTE IMMEDIATE batchStmts;
  END IF;
ELSE
  SET i = -1;

END IF;
CLOSE stmtCursor;
END WHILE;
-- Drop the temporary table
DROP TABLE temp_sql_statements;
END

请协助对齐程序

// JAVA用SQL语句数组调用存储过程

    static void executeStatements(Connection conn, List<String> sqlStatements)
{

    try {
        CallableStatement cstmt = conn.prepareCall("{CALL multiInsertAndUpdate(?)}");

        // Convert the List<String> to a SQL Array
        Array sqlArray = conn.createArrayOf("VARCHAR", sqlStatements.toArray());

        cstmt.setArray(1, sqlArray);
        cstmt.execute();

        sqlArray.free();
        cstmt.close();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

程序因错误无法执行

java sql db2 db2-luw java-stored-procedures
1个回答
0
投票

有趣的程序。我假设您的用法是这样的,您不担心 Java 程序注入了什么 SQL?

我最近经常使用数组,通常是行类型。有关工作(但更复杂)的示例,请参阅我在 https://github.com/easydataservices/db2-auth/blob/main/db2/schema/module_attributes.sql 的 SAVE_ATTRIBUTES 过程,然后查看 Java 代码saveAttributes(String sessionId, List sessionAttributes) 在https://github.com/easydataservices/db2-auth/blob/main/java/src/open/auth/AuthAttributesDao.java

注意第 116 行:

Struct[] attributeStructs = new Struct[sessionAttributes.size()];

还有第141行:

attributeArray = connection.createArrayOf(schemaName + "ATTRIBUTES.SESSION_ATTRIBUTE", attributeStructs);

你看这就是我传递给 createArrayOf(...), Struct[] not Object[] 的内容。在 JDBC 中,任何行类型都是 Struct,因此行类型的数组是 Struct[]。

在您的情况下,VARCHAR 是一个字符串,因此对于 VARCHAR 数组,您应该传递 String[].

希望这有帮助。

© www.soinside.com 2019 - 2024. All rights reserved.