我想使用DB2存储过程从我的Java应用程序中运行多个插入和更新SQL语句。我准备了以下包含错误的过程。
在这个实现中,我首先要创建一个临时表来存储SQL语句。然后使用一个循环,使用一个准备好的语句将SQL语句插入临时表。最后,我们以批处理模式执行SQL语句。
为了从Java应用程序调用这个存储过程,我希望将SQL语句列表作为字符串的List数组传递。
下面是我的步骤:
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();
}
}
由于错误,过程无法执行
1条答案
按热度按时间muk1a3rh1#
有趣的过程。我假设你的用法是这样的,你不担心什么SQL被注入的Java程序?
最近我经常使用数组,通常是与行类型一起使用。
注意第116行:
第141行:
你看,这就是我传递给createArrayOf(...)的东西,Struct[] * 而不是 * Object[]。在JDBC中,任何行类型都是Struct,所以行类型的数组是Struct[]。
在你的例子中,VARCHAR是一个String,所以对于VARCHAR数组,你应该传递String[]。
希望这个有用。