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



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

当前设置

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

    db = new EmbeddedDatabaseBuilder()
             .addDefaultScripts()
             .addScript("stored_procedure.sql")
             .build();
    
  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
    

问题

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

但是,在创建过程时,我看到如下错误,即使在上述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)

资源和提示

我正在使用提供HSQLDB 2.2.4的Spring 3.1.1,根据文档,我认为我正在做正确的事情。

但是,像这样的讨论:

  • 这个
  • 春天的吉拉门票 SPR-8817

让我认为这可能是HSQLDB和Spring之间的不兼容/由处理分隔符的方式引起的错误。

但我是Spring和HSQLDB的初学者,因此我有以下问题。

问题

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

  2. 在 HSQLDB 中使用从位置选择查询返回结果集的等效方法,假设最终存储过程是使用 {call GetFooById ?} 调用

  3. 的?
  4. 由于ResourceDatabasePopulator,这是否有效地发生?资源数据库填充器在Spring 3.1.1中仍然造成麻烦吗?

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

提前非常感谢您的帮助。

米.


编辑:

结论和解决方案

问题

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

  2. {call GetFooById ?}
  3. 是 Sybase(我的生产数据库)的有效语法,但对于 HSQLDB 来说不是,HSQLDB 需要 {call GetFooById(?)}当然,HSQLDB语法也与Sybase的语法不兼容。此外,Spring的JdbcTemplate并没有抽象出这些差异。

解决方案

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

  2. Spring 的 StorageProcedure 类似乎更具可移植性,可以与 Sybase 和 HSQLDB 一起使用,即使它比 JdbcTemplate 更详细一些。

源代码:在我的 GitHub 存储库中可用。

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

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

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

最新更新