如何返回callableStatement结果?

时间:2013-04-03 22:06:08

标签: java function postgresql plpgsql callable-statement

我正在使用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 

我用它调用它,因为我必须声明out值的类型,在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)

但是要在java中的callableStatement中调用它,我使用:

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

但是我得到了一个postgreSQL.exception:

  

返回«record»

的函数需要列的定义列表

所以我使用preparedStatement在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。我怎么能这样做?

2 个答案:

答案 0 :(得分:0)

SQL要求在调用语句时知道返回类型。如果将返回类型声明为匿名记录,则必须为每次调用提供列定义列表。非常笨重。
而是在函数中声明返回类型。

这是一个与所有细节密切相关的答案:
PostgreSQL: ERROR: 42601: a column definition list is required for functions returning "record"

以下是各种半动态回归类型的高级黑魔法:
Refactor a PL/pgSQL function to return the output of various SELECT queries

要明确:返回类型的定义与PL / pgSQL和SQL函数的工作方式相同。

查询

这可能只是SQL function,这更简单:

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类型的名称。只有列的位置是相关的。我将别名留作文档注释。

  • 我的建议是不要在PostgreSQL中使用CamelCase标识符。当没有被双引号包围时,它们会被折叠成小写。

答案 1 :(得分:0)

我用它来解决它...我从create table子句中读了一些... thanks =)

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()