【问题标题】:How to get REF CURSOR data from Oracle store procedure by PreparedStatement?如何通过 PreparedStatement 从 Oracle 存储过程中获取 REF CURSOR 数据?
【发布时间】:2022-08-24 23:02:33
【问题描述】:

我想多次使用过程从 oracle 数据库中获取许多表选择

我的 Oracle 程序

PROCEDURE getInfo(
  Status   IN  VARCHAR2,
  P_CUR    OUT REFCURSOR)
AS
BEGIN
    OPEN P_CUR FOR
    SELECT      *
    FROM        TABLE
    WHERE       TABLE.STATUS = Status
END;

这是我的Java调用程序。它不起作用,我无法为 PreparedStatement 设置 registerOutParameter 来获取光标数据。

PreparedStatement pstmt = null;
pstmt = cnn.prepareCall(\"{call \" + schemaName + \".LOC_EXCHANGE.getInfo(?,?)}\");
for (Entity entity : ListEntity) {
    int i = 1;
    pstmt.setString(i++, entity.getTxnId());
    pstmt.registerOutParameter(i, OracleTypes.CURSOR);
    pstmt.addBatch();
}
pstmt.executeBatch();
cnn.commit();
rs = (ResultSet) pstmt.getObject(i);
  • 你得到什么错误?顺便说一句,当您使用批处理执行时,如果您得到的光标不是上次执行的光标(如果有的话),我会感到惊讶。这不是批处理执行的目的。虽然我可能错了,因为我不经常与 Oracle 合作。
  • 另外registerOutParameterPreparedStatement中没有定义,需要使用CallableStatementprepareCall返回的实际类型)

标签: java oracle stored-procedures jdbc


【解决方案1】:

批量而不是批量获取数据

我不认为你可以批处理这些电话。你可能会做一个匿名块,而不是:

BEGIN
  LOC_EXCHANGE.getInfo(?, ?);
  LOC_EXCHANGE.getInfo(?, ?);
  LOC_EXCHANGE.getInfo(?, ?);
  ...
END;

避免 N+1

就个人而言,我认为您在这里产生了 N+1 问题。与其为每个entity.getTxnId() 获取数据,不如重构getInfo() 过程以允许为txnids 列表返回数据?做这个:

CREATE TYPE txnids AS TABLE OF VARCHAR2(4000);

然后声明:

PROCEDURE getInfo(
  Status   IN  txnids ,
  P_CUR    OUT REFCURSOR)
AS
BEGIN
  OPEN P_CUR FOR
  SELECT *
  FROM TABLE
  WHERE TABLE.STATUS IN (
    SELECT * FROM TABLE (Status)
  )
  ORDER BY TABLE.STATUS
END;

由于您正在投影*,因此在获取所有数据后,您仍然可以访问STATUS 列以便在客户端中对数据进行分组。

【讨论】:

    猜你喜欢
    • 2022-07-21
    • 2014-01-23
    • 1970-01-01
    • 2012-01-23
    • 2016-10-21
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多