0

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

但是要在 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。我怎样才能做到这一点?

4

2 回答 2

0

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

这是与所有详细信息密切相关的答案:
PostgreSQL:错误:42601:返回“记录”的函数需要列定义列表

这里有一些针对各种半动态返回类型的高级黑魔法:
重构 PL/pgSQL 函数以返回各种 SELECT 查询的输出

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

询问

这实际上可能只是一个SQL 函数,这更简单:

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 标识符。当没有被双引号包围时,它们将折叠为小写。

于 2013-04-03T22:24:01.973 回答
0

我用这个解决了它......我从create table子句中读了一些......谢谢=)

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()
于 2013-04-04T05:09:49.970 回答