在java = error中返回SETOF记录的函数

时间:2012-04-27 20:05:52

标签: java sql postgresql

我必须使用PostgreSQL,但是当我尝试用Java读取函数时,我遇到了一些问题。

我的功能:

CREATE OR REPLACE FUNCTION tiena.RecursosData7(x text, OUT id text, OUT valor text)RETURNS SETOF record
AS
'
    SELECT recursodc.idrecursodc, recursodc.valorfonte
    FROM tiena.recursodc
    WHERE valorfonte=$1;
'
LANGUAGE 'sql';

然后在Java中我试图以这种方式读取函数:

try {
    if (AbrirConexao()) {
        conn.setAutoCommit(false);
        proc = conn.prepareCall("{ call tiena.recursosdata7(?,?, ?)}");
        proc.setString(1,"IG - SP");
        proc.registerOutParameter(2, Types.VARCHAR);
        proc.registerOutParameter(3, Types.VARCHAR);

        //proc.execute();
        //resSet = (ResultSet) proc.getObject(1);
        resSet = proc.executeQuery();
        while(resSet.next())
        {
            String id = resSet.getString(1);
            String fonte = resSet.getString(2);
            System.out.println("id : "+ id +", fonte: "+ fonte);
        }
        proc.close();
    }

但我总是得到同样的错误。

Erro : Nenhum resultado foi retornado pela consulta.
org.postgresql.util.PSQLException: Nenhum resultado foi retornado pela consulta.
        at org.postgresql.jdbc2.AbstractJdbc2Statement.executeQuery(AbstractJdbc2Statement.java:274)
        at LerArquivos.ConexaoBD.RecuperarIDRecurso2(ConexaoBD.java:117)
        at upload_cg.Main.main(Main.java:24)

我试图移动参数的位置,功能和我搜索很多,但我没有找到解决方案。你有什么建议吗?

1 个答案:

答案 0 :(得分:0)

Bellninita, 请考虑使用光标。这是一个有效的例子:

protected Fault getFault(Integer buno, Integer faultCode,
        GregorianCalendar downloadTime, IFilterEncoder filter, FaultType faultType, boolean verbose) {
    Fault fault = new Fault(faultCode, 0);
    try {
        // We must be inside a transaction for cursors to work.
        conn.setAutoCommit(false);
        // Procedure call: getFault(integer, text, timestamp, integer)
        proc = conn.prepareCall("{ ? = call getfaultCount(?, ?, ?, ?, ?) }");
        proc.registerOutParameter(1, Types.OTHER);
        proc.setInt(2, buno);
        proc.setInt(3, faultCode);
        Timestamp ts = new Timestamp(downloadTime.getTimeInMillis());
        cal.setTimeZone(downloadTime.getTimeZone());
        proc.setTimestamp(4, ts, cal);
        proc.setInt(5, filter.getEncodedFilter());
        proc.setString(6, faultType.toString());
        proc.execute();
        if(verbose) {
            log.logInfo(this.getClass().getName(), "SQL: " + proc.toString());
        }
        results = (ResultSet) proc.getObject(1);
        while (results.next()) {
            //Do something with the results here
        }
    } catch (SQLException e) {
        //Log or handle exceptions here
    }
    return fault;
}

这是函数内部的SQL(又名存储过程):

CREATE OR REPLACE FUNCTION getfaultcount(_bunoid integer, _faultcode integer, _downloadtime timestamp without time zone, _filterbitmap integer, _faulttype text)
  RETURNS refcursor AS
$BODY$
DECLARE mycurs refcursor;
BEGIN 
    OPEN mycurs FOR
    SELECT count(*) as faultcount, _downloadtime as downloadtime
    FROM    fs_fault f
        JOIN download_time d ON f.downloadtimeid = d.id
    WHERE   f.faultcode = _faultcode
        AND f.statusid IN(2, 4)
        AND d.downloadtime = _downloadtime
        AND d.bunoid = _bunoid 
    GROUP BY f.faultcode
    ;
    RETURN mycurs;
END;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
ALTER FUNCTION getfaultcount(integer, integer, timestamp without time zone, integer, text) OWNER TO postgres;

虽然我的程序看起来很复杂,但它包含了您需要的所有基本组件。我希望这对你有帮助,Bellninita。