В настоящее время я пытаюсь создать тестовую среду, используя экземпляр HSQLDB в -памяти, созданный с использованием Spring, благодаря встроенному поддержка баз данных:
Создание «источника данных» для моих модульных тестов:
db = new EmbeddedDatabaseBuilder() .addDefaultScripts() .addScript("stored_procedure.sql") .build();
Содержимое «сохраненной _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)
Я используя Spring 3.1.1, который предоставляет HSQLDB 2.2.4, и, основываясь на документации, я думаю, что поступаю правильно.
Тем не менее, обсуждения, такие как:
заставляют меня думать, что это может быть несовместимость между HSQLDB и Spring / ошибка, вызванная способом обработки разделителей.
Но я новичок и в Spring, и в HSQLDB, поэтому мои вопросы ниже.
Кто-нибудь видел это раньше? И придумал решение?
Существует ли эквивалентный способ возврата набора результатов с помощью запроса select -from -where в HSQLDB, учитывая, что конечная хранимая процедура вызывается с использованием {call GetFooById ?} ?
Может ли это произойти из-за ResourceDatabasePopulator? ResourceDatabasePopulator по-прежнему вызывает проблемы в Spring 3.1.1?
Любой другой указатель/подсказка?
Заранее большое спасибо за помощь.
M.
EDIT:
Проблемы:
ResourceDatabasePopulator обрабатывает точки с запятой как разделители запросов, что несовместимо с синтаксисом HSQLDB.
{call GetFooById ?} является допустимым синтаксисом для Sybase (моей производственной базы данных ), но не для HSQLDB, который ожидает {call GetFooById (? )} . И, конечно же, синтаксис HSQLDB также несовместим с синтаксисом Sybase. Кроме того, Spring JdbcTemplate не абстрагируется от этих различий.
Решения:
Использование хранимых процедур Java вместо хранимых процедур SQL может быть обходным путем, поскольку запрос написан на стороне Java и не используются разделители с двоеточием -. В качестве альтернативы я предполагаю, что логика ResourceDatabasePopulator может быть изменена и использована для настройки встроенной базы данных, но я пока этого не пробовал.
Класс Spring StoredProcedure кажется гораздо более переносимым и может использоваться как с Sybase, так и с HSQLDB, даже если он немного более многословен, чем JdbcTemplate.
Исходный код:Доступен в моем репозитории GitHub .