java - 如何使用 jdbctemplate 从 Java 执行匿名 PL/SQL
问题描述
我想从 Java 调用这个查询(在 SQL 开发人员上运行时有效)
DECLARE
TYPE my_id_tab IS
TABLE OF my_table.my_id%TYPE;
my_ids my_id_tab;
BEGIN
UPDATE my_table
SET
another_id = NULL
WHERE
another_id IS NULL
AND create_datetime BETWEEN '03-JUN-19' AND '05-JUN-19'
RETURNING my_id BULK COLLECT INTO my_ids;
COMMIT;
END;
但我相信 Java 在试图弄清楚我希望 my_ids 的集合返回给我时遇到了困难。
这是我到目前为止尝试过的异常消息,java.sql.SQLException: Invalid column index
例如
java.sql.SQLException: operation not allowed: Ordinal binding and Named binding cannot be combined!
final Connection connection = DataSourceUtils.getConnection(jdbcTemplate.getDataSource());
try (final CallableStatement callableStatement = connection.prepareCall(TEST_SQL))
{
callableStatement.registerOutParameter("my_ids", Types.ARRAY);
callableStatement.executeUpdate();
int[] arr = (int[]) callableStatement.getArray("my_ids").getArray();
return Arrays.stream(arr).boxed().collect(Collectors.toSet());
}
catch (final SQLException e)
{
LOG.info("threw exception, {}", e);
}
finally
{
DataSourceUtils.releaseConnection(connection, jdbcTemplate.getDataSource());
}
解决方案
这不是最简单的事情,但它很容易做到。您需要在 Oracle 中创建一个 TYPE 来定义结果。
对于此演示,创建并填充 EMP 和 DEPT:EMP 和 DEPT 脚本
创建TYPE
, 需要定义将返回的数组:
create type t_integer_array as table of integer;
我们将运行以下命令UPDATE
,它只会更新几行:
UPDATE emp
SET job = job -- a nonsense update
WHERE comm IS NOT NULL -- only affect some of the rows
这是Java:
package test;
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Types;
import java.util.Arrays;
public class OracleTest {
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(
"<your JDBC url>", "<your user>", "<your password>");
// Prepare the call, without defining the the output variable
// in a DECLARE section of the PL/SQL itself, you just need to
// include a "?" and then associate the correct type in the
// next step.
CallableStatement cs = conn.prepareCall(
"BEGIN\n"
+ " UPDATE emp\n"
+ " SET job = job\n"
+ " WHERE comm is not null\n"
+ " RETURNING empno BULK COLLECT INTO ?;\n"
+ "END;");
// Register the single OUT parameter as an array, using the
// type that was defined in the database, T_INTEGER_ARRAY.
cs.registerOutParameter(1, Types.ARRAY, "T_INTEGER_ARRAY");
cs.execute();
// Now get the array back, as array of BigDecimal.
// BigDecimal is used because it doesn't have precision
// problems like floating point, it will contain all digits
// that the database provided.
BigDecimal[] nums = (BigDecimal[]) (cs.getArray(1).getArray());
System.out.println(Arrays.toString(nums));
cs.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
这是我的输出:
[7499、7521、7654、7844]
这些是empno
仅受更新影响的行的技术密钥 ( )。
推荐阅读
- symfony - 使用 Swiftmailer 在 Heroku 中发送电子邮件的问题
- vue.js - vue-jest 错误:“SyntaxError: Unexpected token <”由`import PictureInput from 'vue-picture-input'`引起
- javascript - 如何在 Three.js 中返回对象而不是将其添加到场景中?(FBXLoader)
- node.js - 如何使用 NodeJS 在 MongoDB 中使用批处理插入数百万个文档
- css - Prestashop 1.6.1.4 - 将 CSS 添加到模块的 CMS 页面
- javascript - 需要一个 JSON 对象、数组或 literal.json
- php - 如何使用 include() 将图像包含在
我需要有关 HTML 和 PHP 的帮助。我如何使用 include() in
<img src"">
?例子:
<?php some code here $page_banner = $_SERVER['DOCUMENT_ROOT'].'/img/page-banner.png'; some co
- node.js - 使用数组 lpush 后的 node_redis rpop
- java - 从 jsonstring jackson lib java 中删除斜杠
- r - 使用 dplyr 将字符向量分组到新组中