使用Spring嵌入式数据库API在HSQLDB中创建存储过程

Mar*_*rré 14 database spring unit-testing stored-procedures hsqldb

我目前正在尝试使用Spring创建的内存中HSQLDB实例来创建测试环境,这得益于其嵌入式数据库支持:

当前设置

  1. 为我的单元测试创​​建"数据源":

    db = new EmbeddedDatabaseBuilder()
             .addDefaultScripts()
             .addScript("stored_procedure.sql")
             .build();
    
    Run Code Online (Sandbox Code Playgroud)
  2. "stored_procedure.sql"的内容:

    -- Mock of a more complex stored procedure in production environment
    CREATE PROCEDURE GetFooById(IN fooId VARCHAR(12))
      READS SQL DATA DYNAMIC RESULT SETS 1
      BEGIN ATOMIC
          DECLARE resultSet CURSOR WITHOUT HOLD WITH RETURN FOR SELECT name, value FROM Foos WHERE id = fooId;
          OPEN resultSet; 
      END
    
    Run Code Online (Sandbox Code Playgroud)

问题

我可以初始化我的架构并从"默认脚本"插入我的测试数据,没有任何问题.

但是,在创建过程时,我发现下面的错误,即使在上面的SQL的不同版本之后,有/没有分隔符,并且在不同的位置有分隔符:

java.sql.SQLSyntaxErrorException: unexpected end of statement:  required: ;
  at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
  at org.hsqldb.jdbc.Util.sqlException(Unknown Source)
  at org.hsqldb.jdbc.JDBCStatement.fetchResult(Unknown Source)
  at org.hsqldb.jdbc.JDBCStatement.executeUpdate(Unknown Source)
  at org.springframework.jdbc.datasource.init.ResourceDatabasePopulator.executeSqlScript(ResourceDatabasePopulator.java:169)
Run Code Online (Sandbox Code Playgroud)

资源和提示

我正在使用提供HSQLDB 2.2.4的Spring 3.1.1,并且根据文档,我认为我做的是正确的.

但是,讨论如下:

  • 这个
  • Spring的JIRA票SPR-8817

让我觉得它可能是HSQLDB和Spring之间不兼容/由分隔符处理方式引起的错误.

但我是Spring和HSQLDB的初学者,因此我的下面的问题.

问题

  1. 有人见过这个吗?想出了解决方案?

  2. 考虑到使用{call GetFooById?}调用最终存储过程,是否存在使用HSQLDB中的select-from-where查询返回结果集的等效方法?

  3. 由于ResourceDatabasePopulator,这有效吗?ResourceDatabasePopulator是否仍然在Spring 3.1.1中引起麻烦?

  4. 还有其他指针/提示吗?

非常感谢您的帮助.

M.


编辑:

结论与解决方案

问题:

  1. ResourceDatabasePopulator将分号作为查询分隔符处理,这不符合HSQLDB的语法.

  2. {call GetFooById?}是Sybase(我的生产数据库)的有效语法,但不适用于HSQLDB,它需要{call GetFooById(?)}.当然,HSQLDB语法也与Sybase的语法不兼容.此外,Spring的JdbcTemplate并没有消除这些差异.

方案:

  1. 使用Java存储过程而不是SQL存储过程可以是一种解决方法,因为查询是在Java端编写的,并且不涉及分号分隔符.或者,我想ResourceDatabasePopulator的逻辑可以更改并用于设置嵌入式数据库,但到目前为止我还没有尝试过.

  2. Spring的StoredProcedure类似乎更具可移植性,可以与Sybase和HSQLDB一起使用,即使它比JdbcTemplate更冗长.

源代码:可在我的GitHub存储库中找到.

小智 1

  1. 对于存储过程和对象类型,您需要关心数据库的 JDBC 驱动程序。对于存储过程,也用于测试或其他,请在数据库中创建一个包并在将来的测试阶段调用它。

  2. 我使用了存储过程和自定义输入/输出对象,仅使用 Java SQL 存储过程 API,并在需要时进行自定义。

如果您想解释您的背景和案例,我们可以帮助您找到最佳解决方案:-)。