簡體   English   中英

java中返回SETOF記錄的函數=錯誤

[英]Function that returns SETOF record in java = error

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

我試圖移動參數的位置,函數,我搜索了很多,但我沒有找到解決方案。 你有什么建議嗎?

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;

盡管我的程序看起來很復雜,但它具有您所需的所有基本組件。 我希望這對您有幫助,Bellinita。

最好的方法是在 SELECT 的 FROM 子句中使用 set 返回函數。 無需使用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();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM