Jaybird CallableStatement 在获取输出参数之前不会执行

2023-12-19

我有这个Java code:

Connection conn = connectionProvider.getConnection();
statement = conn.prepareCall("execute procedure rm_set_coordinates(?,?,?)");
statement.setInt(1, userId);
statement.setString(2, String.valueOf(location.getLatitude()));
statement.setString(3, String.valueOf(location.getLongitude()));
statement.execute();

Where rm_set_coordinates is Firebird存储过程:

create or alter procedure RM_SET_COORDINATES (
    PCAR_LOGIN integer,
    PLAT varchar(20) = 0,
    PLNG varchar(20) = 0)
returns (
    ORESULT integer,
    ORESULT_MSG varchar(500))
as
begin
     update ref_car rc  set rc.rm_last_connect_time='now',rc.rm_lat=:plat,rc.rm_lng=:PLNG  where rc.id=:pcar_login;
     oresult=1;
     oresult_msg='';
  suspend;
end

当我执行此代码数据时ref_car表没有改变。 但是如果我将这一行添加到上面的代码中:

statement.getInt(1);

返回值oresult输出参数就可以了,data inref_car表已更新。


问题是你的使用SUSPEND在存储过程中。关键词SUSPEND适用于可选择的存储过程(生成多行数据的存储过程)。由于您的存储过程仅生成一行,因此SUSPEND是不必要的(以及原因)。

对于可选择的程序,Jaybird 会改变您的execute procedure rm_set_coordinates(?,?,?) to SELECT * FROM rm_set_coordinates(?,?,?)。我不是 100% 确定 Firebird 存储过程的实现细节,但它看起来像一个包含SUSPEND要么仅在实际获取行时执行,要么执行对前一行的所有更改SUSPEND当在语句关闭或重用之前未提取行时,将恢复。

然而,最终结果是:没有获取行,没有更改。当执行一个可选择的存储过程时(即:它包含一个SUSPEND),Jaybird 检索结果的方式与“正常”可执行存储过程不同。

已知可执行存储过程只有一行(或没有行)结果,因此在执行时会立即检索这些值,并且可以使用getXXX()方法。对于可选择的存储过程,结果像平常一样检索ResultSet。通常对于可选择的存储过程,您应该使用executeQuery()并处理ResultSet回。由于实现人工制品以及与旧版本 Firebird 的兼容性(无法区分可选过程和可执行过程),可以检索第一行(或当前行)的值。ResultSet使用getXXX()的方法CallableStatement以及。

TL;DR: 去除SUSPEND.

披露:我是 Jaybird 的开发者之一

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Jaybird CallableStatement 在获取输出参数之前不会执行 的相关文章

随机推荐