Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql Firebird DB上的SimpleJDBCall NullPointerException_Sql_Spring_Stored Procedures_Jdbc_Firebird - Fatal编程技术网

Sql Firebird DB上的SimpleJDBCall NullPointerException

Sql Firebird DB上的SimpleJDBCall NullPointerException,sql,spring,stored-procedures,jdbc,firebird,Sql,Spring,Stored Procedures,Jdbc,Firebird,我在调用Firebird上的存储过程时遇到问题。我的过程有一个参数(UID)并返回一个值ID ... JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); // sp declaration SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate) .withProcedureName("SP_NEWRECORD").declareParameters(

我在调用Firebird上的存储过程时遇到问题。我的过程有一个参数(UID)并返回一个值ID

...
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
// sp declaration
SimpleJdbcCall jdbcCall = new SimpleJdbcCall(jdbcTemplate)
      .withProcedureName("SP_NEWRECORD").declareParameters(
       new SqlParameter("UID", Types.INTEGER),
       new SqlOutParameter("NEWID", Types.INTEGER));
Map<String, Object> in = new HashMap<String, Object>();
in.put("UID", uid);
in.put("NEWID", 0);

try {
Map<String, Object> out = jdbcCall.execute(in); //here throws Exception
    last_inserted = Integer.parseInt(String.valueOf(out.get("NEWID")));
} catch (Exception ex) {
    ex.printStackTrace();
} finally {
    System.out.println("createRecord result id=" + last_inserted);
}
// return id of inserted record
return last_inserted;
SP的代码非常简单,在表中创建新记录并返回插入记录的ID

ALTER PROCEDURE SP_NEWRECORD (UID integer)
RETURNS (NEWID integer)
AS
declare variable ID integer;
begin
  ID=GEN_ID(gen_myrecords_id,1);
  insert into myrecords (id,uid)
  values (:id,:uid);
  newid=ID;
end

最终的问题是,目前Jaybird没有明确区分
OUT
参数(Firebird技术上没有)、可执行过程的(单行)返回值和可选择存储过程的(多行)结果集。您遇到的问题(至少部分)与(以及对计划用于Jaybird 3.0的
CallableStatement
实现的一般审查)有关

这会导致这样一种情况:支持单行的结果集被读取两次,一次作为
ResultSet
读取,一次通过
CallableStatement
上的getter读取,但是由于支持结果集已关闭,因此在检索
OUT
参数时会导致
NullPointerException

有两种可能的解决办法:

  • JdbcTemplate
    上禁用结果处理:

    JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
    jdbcTemplate.setSkipResultsProcessing(true);
    
  • 不要声明
    OUT
    参数,并处理
    OUT
    映射中返回的结果集(其中包含一个
    列表,其中包含一个
    映射,用于结果集):

    last_inserted=(int)((List)out.get(“#result-set-1”)).get(0.get(“NEWID”);
    
  • 请注意,从
    Object
    int
    的转换采用Java7或更高版本


    我已将此特定问题报告为,我将在下一个Jaybird版本(2.2.6)中尝试解决此问题。

    您使用的是哪一个Jaybird版本?firebird版本是2.5,Jaybird版本是2.1.6您可以尝试吗?没有任何更改。但我不明白,为什么是System.out.println(jdbcCall.getCallString());返回{call SP_NEWRECORD(?,)},但Firebird使用“EXECUTE PROCEDURE”语句而不是“call”
    {call…}
    是存储过程的JDBC转义,所有驱动程序都需要支持它。Jaybird将其转换为特定于Firebird的语法。但是,我想知道这个问题是否是由于您将返回值注册为OUT参数引起的。我需要检查一下,然后再打给你。您可能希望尝试删除OUT参数的声明,并改用
    withReturnValue()
    。但不确定这是否有效。那么,在Jaybird3.0之前,您有什么建议?我们是否应该(例如,在向添加SP支持时)简单地生成PSQL以获取那些“
    OUT
    ”参数,而不是使用JDBC转义语法?@LukasEder最简单的方法是将一切都视为可选择的(生成
    结果集
    ),这应该适用于所有现有的Jaybird版本。这甚至在使用JDBC转义语法时也有效:只需在
    参数中指定
    。但是,对于Jaybird 3来说,保持这种兼容性可能会让我有些头疼;)太晚了。现在,它是按照您的建议实现的:)@LukasEder我可能只是添加了一个限制,您不能同时使用
    ResultSet
    -like和
    OUT
    。是的。如果我相信您有表值函数,那么SQL Server也不支持这一点。但是您可以在SQL Server中拥有
    OUT
    参数和随机(未声明)结果集。无论如何,如果有疑问,我相信HSQLDB在例程方面是相当符合标准的。。。
    JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
    jdbcTemplate.setSkipResultsProcessing(true);
    
    last_inserted = (int) ((List<Map>) out.get("#result-set-1")).get(0).get("NEWID");