Как вернуть результат callableStatement?

Я использую PostgreSQL, и у меня есть функция, которая возвращает запись:

CREATE OR REPLACE FUNCTION fn_lisMatricula()
  RETURNS record AS
$BODY$
SELECT mat.codigo as codmatr, mat.codigoalumno as codal, mat.codigoempresa as codemp ,mat.codigopresentacion as codpre,
    mat.codigosecretaria as codsec, mat.fecha as fechamat, mat.estado as estadomat,
    mat.vigencia as vigmat, p.apellidos as apeAl,
    p.nombres as nomAl,razonsocial ,pre.codigocurso as codcur,cur.nombre as curso
    FROM matricula mat join alumno al on mat.codigoalumno = al.codigoalumno
    join persona p on  al.codigoalumno = p.codigo
    join persona pe on mat.codigoalumno = pe.codigo
    left join empresa emp on mat.codigoempresa = emp.codigo
    join presentacion pre on mat.codigopresentacion = pre.codigo
    join curso cur on cur.codigo = pre.codigocurso
    order by p.apellidos
$BODY$
  LANGUAGE sql VOLATILE 

Я называю это так, потому что я должен объявить тип выходных значений, который отлично работает в Postgres:

select * from fn_lisMatricula() as (codmatr integer,codal integer,codemp integer,codpre integer,codsec integer,fechamat date,
estadomat char,vigmat boolean,apeal varchar,nomal varchar,razonsocial varchar,codcur integer,curso varchar)

Но чтобы вызвать это в callableStatement в java, я использую:

proc = this.cn.prepareCall("{call fn_lisMatricula()}")

Но я получаю postgreSQL.exception:

список определения столбцов требуется функциям, возвращающим «запись»

Поэтому я временно решил это на Java с помощью подготовленного заявления:

PreparedStatement ps;
String SQL = "select * from fn_lisMatricula() as (codmatr integer,codal integer,codemp integer,codpre integer,codsec integer,fechamat date,\n"
                    + "estadomat char,vigmat boolean,apeal varchar,nomal varchar,razonsocial varchar,codcur integer,curso varchar)";

ps = this.cn.prepareStatement(SQL);

Я хочу использовать callableStatement. Как я могу это сделать?


person MitoCode    schedule 03.04.2013    source источник


Ответы (2)


Я решаю это с помощью этого ... я прочитал кое-что из пункта создания таблицы ... спасибо =)

CREATE OR REPLACE FUNCTION fn_lisMatricula()
  RETURNS TABLE (codmatr integer,codal integer,codemp integer,codpre integer,codsec integer,fechamat date,
estadomat char,vigmat boolean,apeal varchar,nomal varchar,razonsocial varchar,codcur integer,curso varchar) AS
$BODY$
BEGIN
RETURN QUERY
SELECT mat.codigo as codmatr, mat.codigoalumno as codal, mat.codigoempresa as codemp ,mat.codigopresentacion as codpre,
    mat.codigosecretaria as codsec, mat.fecha as fechamat, mat.estado as estadomat,
    mat.vigencia as vigmat, p.apellidos as apeAl,
    p.nombres as nomAl,emp.razonsocial ,pre.codigocurso as codcur,cur.nombre as curso
    FROM matricula mat join alumno al on mat.codigoalumno = al.codigoalumno
    join persona p on  al.codigoalumno = p.codigo
    join persona pe on mat.codigoalumno = pe.codigo
    left join empresa emp on mat.codigoempresa = emp.codigo
    join presentacion pre on mat.codigopresentacion = pre.codigo
    join curso cur on cur.codigo = pre.codigocurso
    order by p.apellidos;
END
$BODY$ 
LANGUAGE plpgsql;

select * from fn_lisMatricula()
person MitoCode    schedule 04.04.2013
comment
Я добавил обзор вашей функции в свой ответ. - person Erwin Brandstetter; 05.04.2013

SQL требует знать тип возвращаемого значения во время вызова оператора. Если вы объявляете возвращаемый тип как анонимную запись, вы должны предоставлять список определений столбцов при каждом вызове. Очень громоздко.
Вместо этого объявите возвращаемый тип в функции.

Вот тесно связанный ответ со всеми подробностями:
PostgreSQL: ОШИБКА: 42601: для функций, возвращающих запись, требуется список определений столбцов

А вот продвинутая черная магия для различных полудинамических типов возврата:
Рефакторинг функции PL/pgSQL для возврата результатов различных запросов SELECT

Для ясности: определение возвращаемого типа работает одинаково с функциями PL/pgSQL и SQL.

Запрос

На самом деле это может быть просто функция SQL< /a>, это проще:

CREATE OR REPLACE FUNCTION fn_lis_matricula()
  RETURNS TABLE (
        codmatr integer
      , codal integer
      , codemp integer
      , codpre integer
      , codsec integer
      , fechamat date
      , estadomat char
      , vigmat boolean
      , apeal varchar
      , nomal varchar
      , razonsocial varchar
      , codcur integer
      , curso varchar) AS
$BODY$
SELECT mat.codigo               -- as codmatr
      , mat.codigoalumno        -- as codal
      , mat.codigoempresa       -- as codemp
      , mat.codigopresentacion  -- as codpre
      , mat.codigosecretaria    -- as codsec
      , mat.fecha               -- as fechamat
      , mat.estado              -- as estadomat
      , mat.vigencia            -- as vigmat
      , p.apellidos             -- as apeAl
      , p.nombres               -- as nomAl
      , emp.razonsocial
      , pre.codigocurso         -- as codcur
      , cur.nombre              -- as curso
FROM matricula mat
JOIN alumno al ON mat.codigoalumno = al.codigoalumno
JOIN persona p ON al.codigoalumno = p.codigo
JOIN persona pe ON mat.codigoalumno = pe.codigo
JOIN presentacion pre ON mat.codigopresentacion = pre.codigo
JOIN curso cur ON cur.codigo = pre.codigocurso
LEFT JOIN empresa emp ON mat.codigoempresa = emp.codigo
ORDER BY p.apellidos;
$BODY$ 
LANGUAGE sql;
  • Обратите внимание, что псевдонимы столбцов в теле функции — это просто шум. Они отбрасываются в пользу имен типа RETURN. Имеет значение только положение столбца. Я оставил псевдонимы в качестве комментариев для документации.

  • Мой постоянный совет — не использовать идентификаторы CamelCase с PostgreSQL. Если они не заключены в двойные кавычки, они преобразуются в нижний регистр.

person Erwin Brandstetter    schedule 03.04.2013
comment
спасибо, я прочитал некоторые из ваших ссылок, и я прочитал больше из предложения таблицы возвратов, и я решил это, спасибо - person MitoCode; 04.04.2013