Set di risultati nulli quando si chiama la procedura memorizzata di Sybase tramite JDBC

Sto chiamando una procedura memorizzata Sybase che restituisce più set di risultati tramite JDBC. Ho bisogno di ottenere un set di risultati specifico che abbia una colonna chiamata “Result” Questo è il mio codice:

CallableStatement cs = conn.prepareCall(sqlCall); cs.registerOutParameter(1, Types.VARCHAR); cs.execute(); ResultSet rs=null; int count = 1; boolean flag = true; while (count < 20000 && flag == true) { cs.getMoreResults(); rs = cs.getResultSet(); if (rs != null) { ResultSetMetaData resultSetMetaData = rs.getMetaData(); int columnsCount = resultSetMetaData.getColumnCount(); if (resultSetMetaData.getColumnName(1).equals("Result")) { // action code resultset found flag = false; // loop on the resultset and add the elements returned to an array list while (rs.next()) { int x = 1; while (x <= columnsCount) { result.add(rs.getString(x)); x++; } } result.add(0, cs.getString(1)); } } count++; } 

Quello che succede qui è che cs.getMoreResults restituisce molti cs.getMoreResults di risultati nulli fino a raggiungere quello di destinazione. Non riesco a utilizzare cs.getMoreResults come condizione del ciclo perché restituisce false per set di risultati nulli.

Ho inserito un numero fisso per terminare il ciclo in condizione che il set di risultati desiderato non fosse stato restituito per impedirgli di entrare nel ciclo infinito. Ha funzionato bene ma non penso che sia giusto.

Penso che i risultati nulli restituiti dall’assegnazione in Sybase select @variable = value

Qualcuno ha affrontato questo prima?

    Stai interpretando erroneamente il valore restituito da getMoreResults() . Stai anche ignorando il valore restituito da execute() , questo metodo restituisce un valore boolean indica il tipo del primo risultato:

    • true : result è un ResultSet
    • false : il risultato è un conteggio di aggiornamento

    Se il risultato è true , si utilizza getResultSet() per recuperare il ResultSet , altrimenti getUpdateCount() per recuperare il conteggio degli aggiornamenti. Se il conteggio degli aggiornamenti è -1 , significa che non ci sono più risultati. Si noti che il conteggio degli aggiornamenti sarà anche -1 quando il risultato corrente è un ResultSet . È anche utile sapere che getResultSet() dovrebbe restituire null se non ci sono più risultati o se il risultato è un conteggio di aggiornamento (quest’ultima condizione è il motivo per cui si ottengono così tanti valori null ).

    Ora se vuoi recuperare più risultati, chiami getMoreResults() (o suo fratello che accetta un parametro int ). Il valore di ritorno di boolean ha lo stesso significato di execute() , quindi false non significa che non ci siano più risultati !

    Non ci sono più risultati se getMoreResults() restituisce false e getUpdateCount() restituisce -1 (come documentato anche in Javadoc)

    Essenzialmente questo significa che se vuoi elaborare correttamente tutti i risultati devi fare qualcosa di simile qui sotto:

     boolean result = stmt.execute(...); while(true) { if (result) { ResultSet rs = stmt.getResultSet(); // Do something with resultset ... } else { int updateCount = stmt.getUpdateCount(); if (updateCount == -1) { // no more results break; } // Do something with update count ... } result = stmt.getMoreResults(); } 

    La mia ipotesi è che si ottengano molti conteggi di aggiornamento prima di ottenere il ResultSet effettivo.

    Non ho molta familiarità con Sybase, ma suo cugino SQL Server ha la funzione ‘fastidiosa’ per restituire i conteggi degli aggiornamenti dalle stored procedure se non si inserisce esplicitamente SET NOCOUNT ON; all’inizio della procedura memorizzata.

    NOTA: Parte di questa risposta si basa sulla mia risposta all’esecuzione di “sp_msforeachdb” in un’applicazione Java