1

我必须使用 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)

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

4

2 回答 2

0

Bellninita,请考虑改用游标。以下是示例 Java 和 SQL 代码,它们的组件与您似乎需要的相似。这类似于用于相同目的的生产代码:

protected Fault getFault(Integer dataCode, Integer faultCode,
        GregorianCalendar downloadTime, IFilterEncoder filter, FaultType faultType, boolean verbose) {
    // verbose: flag to display logging statements.
    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, dataCode);
        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(_dataCodeid 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.dataCodeid = _dataCodeid 
    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;
于 2012-04-27T21:27:08.483 回答
0

最好的方法是在 SELECT 的 FROM 子句中使用集合返回函数。无需使用 a CallableStatement,常规的PreparedStatement就可以了。

PreparedStatement pstmt = conn.prepareStatement("select * from tiena.recursosdata7(?)");
proc.setString(1,"IG - SP");
ResultSet resSet = pstmt.executeQuery();
while(resSet.next())
{
    String id = resSet.getString(1);
    String fonte = resSet.getString(2);
    System.out.println("id : "+ id +", fonte: "+ fonte);
}
pstmt.close();
于 2021-11-15T19:16:28.180 回答