Хранимая процедура Java и PostgreSQL - возвращает зарегистрированный параметр out, вызывая проблемы с параметрами - PullRequest
1 голос
/ 17 февраля 2010

Я пытаюсь вызвать хранимую процедуру PostgreSQL из приложения Java; процедура имеет параметр типа DATE, поэтому я использую тип java.sql.Date с CallableStatement.setDate (). Однако выполнение оператора всегда приводит к исключению, и журналы SQL показывают это:

LOG:  execute <unnamed>: select * from athlete.create_athlete($1,$2,$3,$4,$5,$6,$7) as result
DETAIL:  parameters: $1 = '', $2 = 'foo@bar.com', $3 = 'Joe', $4 = 'Blow', $5 = 'foobar', $6 = 'M', $7 = '1979-03-22 -04:00:00'
ERROR:  column "dob" is of type date but expression is of type text at character 122
HINT:  You will need to rewrite or cast the expression.
QUERY:  INSERT INTO athlete.athlete (email, first_name, last_name, password, gender, dob) VALUES ( $1 ,  $2 ,  $3 ,  $4 ,  $5 ,  $6 )
CONTEXT:  PL/pgSQL function "create_athlete" line 2 at SQL statement
STATEMENT:  select * from athlete.create_athlete($1,$2,$3,$4,$5,$6,$7) as result

Хранимая процедура на самом деле имеет 6 параметров (и должна получать значения от $ 2 до $ 7 выше) - седьмое происходит от регистрации возвращаемого значения в качестве параметра out. Это меня смутило - правильно ли, что оно отображается как 7 параметров, когда я регистрирую выходной параметр для возвращаемого значения?

Из всех прочитанных мной документов у меня сложилось впечатление, что возвращаемое значение должно быть зарегистрировано в качестве первого параметра:

registerQuery = "{? = call athlete.create_athlete(?,?,?,?,?,?)}";
...
CallableStatement cs = conn.prepareCall(registerQuery);
cs.registerOutParameter(1, Types.BOOLEAN);
cs.setString(2, email);
...

Вышеприведенная ошибка подсказывает мне, что существует несоответствие между параметрами хранимой процедуры и параметрами, переданными в оператор вставки. Я следил за документацией для всего этого, но явно делал что-то не так. Как предоставить правильные параметры для хранимой процедуры и получить возвращаемое значение после вызова?

Ответы [ 4 ]

4 голосов
/ 17 февраля 2010

Зависит от подписи типа хранимой процедуры (функция / процедура).

Для функции, подобной приведенной ниже, выходной параметр будет первым и будет иметь параметры param1 и param2 в качестве второго и третьего параметров.

DB Процедура (для функции):

CREATE FUNCTION my_func (
param1 INT,
param2 INT) 
    RETURNS INT
AS 
    :
    :

Java-код (для функции):

registerQuery = "{? = call my_func(?,?)}";
...
CallableStatement cs = conn.prepareCall(registerQuery);
cs.registerOutParameter(1, Types.INTEGER);
cs.setInteger(2, 10);
cs.setInteger(3, 10);
...

.

Однако для процедуры, подобной приведенной ниже, параметр out будет третьим и будет иметь param1 и param2 в качестве первого и второго параметров.

DB Процедура (для процедуры):

CREATE PROCEDURE my_proc (
param1 INT,
param2 INT,
OUT param3 INT)
BEGIN
    :
    :
END;

Java-код (для процедуры):

registerQuery = "{call my_func(?,?,?)}";
...
CallableStatement cs = conn.prepareCall(registerQuery);
cs.registerOutParameter(3, Types.INTEGER);
cs.setInteger(1, 10);
cs.setInteger(2, 10);
...

.

Обратите внимание, что вы можете иметь несколько выходных параметров, в то время как только одно возвращаемое значение.

1 голос
/ 19 января 2011

Сервер Postgresql поддерживает именованные параметры, но драйвер jdbc не поддерживает его (ну, пока я не знаю), поэтому до этого времени поддерживаются только позиционные параметры.

0 голосов
/ 04 июля 2013

Из-за ограничения на уровне OCI драйверы JDBC не поддерживают передача параметров BOOLEAN в хранимые процедуры PL / SQL. Если PL / SQL Процедура содержит BOOLEAN значения, вы можете обойти ограничение по обертывание процедуры PL / SQL второй процедурой PL / SQL, которая принимает аргумент как INT и передает его первой хранимой процедуре. когда вторая процедура вызывается, сервер выполняет преобразование из INT в BOOLEAN.

0 голосов
/ 02 марта 2010

Оказывается, проблема в том, что порядок параметров, передаваемых хранимой процедуре, не соответствует порядку, в котором эти параметры были переданы в оператор вставки. Я не понимаю, почему PostgreSQL будет использовать именованные параметры, если порядок значим.

Например, подпись хранимой процедуры была следующей:

CREATE FUNCTION insert_Person (IN in_name TEXT, IN in_gender CHAR(1), IN in_bdate DATE) RETURNS BOOLEAN...

Оператор INSERT, содержащийся в этой хранимой процедуре, был следующим:

INSERT INTO Person (name, bdate, gender) VALUES (in_name, in_bdate, in_gender);

Изменение порядка параметров так, чтобы они соответствовали либо сигнатуре хранимой процедуры, либо оператору вставки (я пошел с первым), решило проблему.

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