15

我目前正在尝试使用使用 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,并且根据文档,我认为我在做正确的事情。

但是,讨论如下:

  • 这个
  • 春天的 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(我的生产数据库)的有效语法,但不适用于需要{call GetFooById(?)}的 HSQLDB 。当然,HSQLDB 语法也不兼容 Sybase 的语法。此外,Spring 的 JdbcTemplate 并没有抽象出这些差异。

解决方案

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

  2. Spring 的 StoredProcedure 类似乎更便携,可以与 Sybase 和 HSQLDB 一起使用,即使它比 JdbcTemplate 更冗长。

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

4

1 回答 1

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

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

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

于 2014-01-05T12:02:37.133 回答