HsqlException: общая ошибка при вызове хранимой процедуры - PullRequest
0 голосов
/ 18 октября 2019

Я пытаюсь написать интеграционный тест для DAO, который вызывает хранимую процедуру. Я создал встроенную базу данных HSQL из тестового файла, который просто создает таблицу, заполняет ее и выполняет простую хранимую процедуру, которая возвращает результаты таблицы:

CREATE PROCEDURE usp_GetAvailableServices()
READS SQL DATA
BEGIN ATOMIC
    DECLARE result CURSOR WITH RETURN FOR SELECT FeatureType FROM PUBLIC.service_areas ;
    OPEN result;
END/;

Код для создания базы данных:следующее. База данных создана и заполнена правильно.

        db = new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.HSQL)
                .addScript("db/sql/getAvailableServicesStoredProcedure.sql")
                .setSeparator("/;")
                .build();

Мой тест не пройден при попытке вызвать хранимую процедуру с General error; nested exception is java.sql.SQLException: General error, что в конечном итоге вызвано

Caused by: org.hsqldb.HsqlException: General error
    at org.hsqldb.error.Error.error(Unknown Source)
    at org.hsqldb.error.Error.error(Unknown Source)
    ...

Я запустил консоль HSQLDB и подтвердил, что моя хранимая процедура быладействительно создан (он указан в разделе information_schema.routines), однако, когда я пытаюсь вызвать хранимую процедуру непосредственно в консоли с помощью call usp_GetAvailableServices(), мне все еще предоставляется General error / Error Code: -458 / State: S1000

. Это наводит меня на мысль, что яВ синтаксисе моей процедуры создания есть ошибка (кажется правильным для http://hsqldb.org/doc/2.0/guide/sqlroutines-chapt.html#src_psm_cursors) или что я не знаю, как правильно вызывать процедуру в HSQLDB.

Код, который вызывает живую хранимую процедуру, используяSqlServer работает нормально, только HSQLDB не работает.

1 Ответ

0 голосов
/ 18 октября 2019

Ваша процедура в порядке. Поскольку он использует OPEN cursorname CURSOR, вы не можете вызвать его с помощью DatabaseManager или SqlTool. Вы должны вызывать его таким образом в JDBC, используя execute ():

    CallableStatement cs = conn.prepareCall(
        "call usp_GetAvailableServices()");
    boolean isResult = cs.execute();

    assertFalse(isResult);

    isResult = cs.getMoreResults();

    ResultSet rs = cs.getResultSet();

    rs.next();
    // do something with the rs row
    rs.close();

Обратите внимание на необходимость вызова getMoreResults ().

В качестве альтернативы используйте executeQuery (), чтобы избежать дополнительного вызова.

    CallableStatement cs = conn.prepareCall(
        "call usp_GetAvailableServices()");

    ResultSet rs = cs.executeQuery();

    rs.next();
    // do something with the rs row
    rs.close();

Следующая версия, в настоящее время доступная как jar снимков с http://hsqldb.org/downlaod,, поддерживает cs.execute () и cs.getResultSet () без cs.getMoreResults ().

    CallableStatement cs = conn.prepareCall(
        "call usp_GetAvailableServices()");
    boolean isResult = cs.execute();

    ResultSet rs = cs.getResultSet();

    rs.next();
    // do something with the rs row
    rs.close();
...