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

Java 在获取输出参数之前,不会执行Jaybird CallableStatement,java,stored-procedures,jdbc,callable-statement,jaybird,Java,Stored Procedures,Jdbc,Callable Statement,Jaybird,我有这个Java代码: Connection conn = connectionProvider.getConnection(); statement = conn.prepareCall("execute procedure rm_set_coordinates(?,?,?)"); statement.setInt(1, userId); statement.setString(2, String.valueOf(location.getLatitude())); statement.setS

我有这个
Java
代码:

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();
其中
rm\u set\u坐标
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\u car
表中的数据没有改变。 但如果我将这一行添加到上述代码中:

statement.getInt(1);

它返回
oresult
输出参数的值,然后就可以了,
ref\u car
表中的数据被更新。

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

对于可选择的过程,Jaybird将
execute过程rm_set_坐标(?,?)
转换为
SELECT*FROM rm_set_坐标(?,?)
。我不能100%确定Firebird存储过程的实现细节,但它看起来像是一个包含
SUSPEND
的块,它要么仅在实际提取行时执行,要么在关闭或重用语句之前未提取行时,恢复到上一个
SUSPEND
之前的所有更改

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

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

TL;灾难恢复:删除
挂起

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