Могу ли я вызвать postgres «Процедура» (не «функция») из Java с помощью драйвера JDBC postgres? - PullRequest
0 голосов
/ 05 декабря 2018

Я новичок в postgres, но пытаюсь вызвать процедуру в Postgres 11 (новая «процедура», а не «функция»), вызывая из java как пружинный SimpleJDBCCall (используя драйвер jdbc Postgresql-42.2.5).Однако при выполнении процедуры я сталкиваюсь со следующим исключением:

org.springframework.jdbc.BadSqlGrammarException: CallableStatementCallback;плохая грамматика SQL [{call pa_test_schema.pr_dosomething (?)}];Вложенное исключение: org.postgresql.util.PSQLException: ОШИБКА: pa_test_schema.pr_dosomething (bigint) - это процедура Подсказка: чтобы вызвать процедуру, используйте CALL.Позиция: 15 в org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate (SQLStateSQLExceptionTranslator.java:101) в org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate (AbstractFallbackSQLExceptionTranslator.java:72) в org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate (AbstractFallbackSQLExceptionTranslator.java:81) при org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate (AbstractFallbackSQLExceptionTranslator.java:81) при org.springframework.jdbc.core.JdbcTemplate.translateException (JdbcTemplate.java:1402) в орг.springframework.jdbc.core.(AbstractJdbcCall.java:414) в org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute (AbstractJdbcCall.java:397) в org.springframework.jdbc.core.simple.SimpleJdbcCall.execute (SimpleJdbcCall.java:193)

Мой код процедуры:

CREATE PROCEDURE pa_test_schema.pr_DoSomething
( P_input_ID IN inputs.input_ID%TYPE
) AS $$
BEGIN
    -- do something   
END; 
$$ LANGUAGE plpgsql;

Мой код Java:

SimpleJdbcCallOperations pr_DoSomething =  new SimpleJdbcCall(jdbcTemplate)
        .withSchemaName("pa_test_schema")
        .withProcedureName("pr_DoSomething");
Map<String, Object> inputs = Maps.newHashMap();
inputs.put("p_input_id", 123456);

pr_DoSomething.execute(inputs);    

КогдаПошагово просматривая код, я вижу, что драйвер модифицирует sql оператора вызова для синтаксиса, необходимого для вызова функции postgres:

select * from pa_test_schema.pr_dosomething (?) Как результат

Это метод в драйвере, который выполняет это преобразование: https://github.com/pgjdbc/pgjdbc/blob/faab499853c56f67cb70fb242f75b918452f2a6f/pgjdbc/src/main/java/org/postgresql/core/Parser.java#L766

Я понимаю, что процедуры были введены только в Postgres 11 (ранее можно было использовать функции, возвращающие void) ипрочитал документацию по драйверу postgres, но не вижу ссылки на вызывающие процедуры, а не на функции.

Означает ли это, что текущий драйвер postgres еще не поддерживает это или есть другой подход, который я должен использовать?Должен ли я просто использовать вместо этого функции postgres?

1 Ответ

0 голосов
/ 05 декабря 2018

В настоящее время (начиная с Postgres 11.1 и версии драйвера 42.2.5) стандартный подход JDBC с использованием CallableStatement нельзя использовать для вызова хранимой процедуры.

На самом деле я не использую Spring JDBC Template, но следующий код работает на простом JDBC и должен быть адаптирован к Spring JDBC Tempalte:

Connection con = DriverManager.getConnection(...);
PreparedStatement pstmt = con.prepareStatement("call pa_test_schema.pr_DoSomething(?)");
pstmt.setInt(1, 42);
pstmt.execute();

Обратите внимание, что для этого используется Postgres 'call команда.Не путайте это с синтаксисом "{call ...}" для CallableStatement.


Некоторые подробности о том, почему в настоящее время CallableStatement не работает, можно найти в списке рассылки JDBC здесь и здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...