Могу ли я вызвать процедуру postgres (не функцию) из java с помощью драйвера JDBC postgres?

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

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.AbstractFallbackSQLExworknslator.jdbc. AbstractFallbackSQLExceptionTranslator.translate (AbstractFallbackSQLExceptionTranslator.java:81) по адресу org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate (AbstractFallbackSQLExceptionTranslator.translate (AbstractFallbackSQLExceptionTranslator.translate) (AbstractFallbackSQLExceptionTranslator. .springframework.jdbc.core.JdbcTemplate.execute (JdbcTemplate.java:1065) по адресу org.springframework.jdbc.core.JdbcTemplate.call (JdbcTemplate.java:1104) по адресу org.springc.frameCallCoreCore.JD (AbstractJdbcCall.java:414) в org.springframework.jdbc.core.simple.AbstractJdbcCall.doExecute (Abs tractJdbcCall.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:

выберите * из pa_test_schema.pr_dosomething (?) в качестве результата

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

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

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


person misspelt_yoof    schedule 05.12.2018    source источник


Ответы (1)


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

На самом деле я не использую шаблон Spring JDBC, но следующий код работает с простым 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 здесь и здесь

person a_horse_with_no_name    schedule 05.12.2018