Java 获取存储过程响应



如何在 java 中获取存储过程响应?当我在SQL中运行它时,我得到一个响应

DECLARE
result NUMBER;
begin
  result := apps.xx01_cpc_ap_pkg.xx01_create_invoice_f(8309, 4795, 146.00);
  dbms_output.put_line(result);
end;

这是我的Java代码我尝试了很多选项 - 但我在如何获取响应方面一直失败在这一部分中resultSet.getInt(4))

CallableStatement stmt = null;
String spCallRequest = "{? = call apps.xx01_cpc_ap_pkg.xx01_create_invoice_f(?, ?, ?  )}";
stmt = oraAppUtils.connection.prepareCall(spCallRequest);
stmt.setString(1,paymentRequest.healthFacilityCode);
stmt.setString(2,paymentRequest.batchId);               
stmt.setDouble(3,Double.parseDouble(paymentRequest.tariffAmount));
stmt.registerOutParameter(4, java.sql.Types.INTEGER);
resultSet = stmt.executeQuery();
System.out.println ("invoice id ="+resultSet.getInt(4));

好的 - 仅用于文档,以防其他人需要它...... 这是它有一个功能的SP

CREATE OR REPLACE PACKAGE APPS.XX01_CPC_AP_PKG
AS
PROCEDURE XX01_CREATE_INVOICE (P_HF_CODE IN VARCHAR2,
                               P_BATCH_ID IN VARCHAR2,
                               P_AMOUNT IN NUMBER,
                               x_invoice_id OUT NUMBER/*,
                               x_error_code OUT VARCHAR2,
                               x_error_msg  OUT VARCHAR2,
                               x_err_comments OUT VARCHAR2,
                               x_code OUT NUMBER,
                               x_source OUT VARCHAR2*/);
FUNCTION XX01_CREATE_INVOICE_F (P_HF_CODE IN VARCHAR2,
                               P_BATCH_ID IN VARCHAR2,
                               P_AMOUNT IN NUMBER) RETURN NUMBER;

如此原始,我调用了该函数 - 它不起作用 - 我将代码更改为以下代码并且它可以工作

String spCallRequest = "BEGIN  apps.xx01_cpc_ap_pkg.xx01_create_invoice(?, ?, ?,? ); END ; ";
stmt = oraAppUtils.connection.prepareCall(spCallRequest);
stmt.setString(1,paymentRequest.healthFacilityCode);
stmt.setString(2,paymentRequest.batchId);
stmt.setDouble(3,Double.parseDouble(paymentRequest.tariffAmount));
stmt.registerOutParameter(4, java.sql.Types.INTEGER);
stmt.execute();
System.out.println ("invoice id ="+stmt.getInt(4));

TL;DR

您没有调用 ResultSet#next((

原因

从链接的文档:

ResultSet 游标最初位于第一行之前;该 对方法的第一次调用 next 使第一行成为当前行;这 第二次调用使第二行成为当前行,依此类推。

修复

您的代码应如下所示:

stmt.registerOutParameter(4, java.sql.Types.INTEGER);
resultSet = stmt.executeQuery();
if(resultSet.next()) {
    System.out.println ("invoice id ="+resultSet.getInt(4));
} else {
    //this should not happen
}

您的问题没有明确提到 JDBC 是您必须使用的 API,所以也许您对在 JDBC 上运行的第三方实用程序持开放态度?例如,jOOQ 的代码生成器可用于为所有存储过程生成存根。在您的情况下,您可以像这样简单地调用存根:

int result = Xx01CpcApPkg.xx01CreateInvoiceF(
    configuration, // This object contains your JDBC Connection
    paymentRequest.healthFacilityCode,
    paymentRequest.batchId,
    Double.parseDouble(paymentRequest.tariffAmount)
);

这些对象由 jOOQ 生成:

  • Xx01CpcApPkg:代表您的 PL/SQL 包的类
  • xx01CreateInvoiceF():表示存储函数的方法

在幕后,这完全符合公认的答案,但是:

  • 您不必使用字符串
  • 您不必记住数据类型和参数顺序
  • 当您更改数据库中的过程并重新生成代码时,您的客户端代码将停止编译,因此您会尽早注意到问题

免责声明:我在jOOQ背后的公司工作。

最新更新