Use execute() and getMoreResults() methods for those pesky complex SQL queries

Published Mar 23 2019 10:59 AM 284 Views
Microsoft
First published on MSDN on Aug 01, 2008

Per JDBC spec, the Statement.executeUpdate() and Statement.executeQuery() methods are to be used only with queries that produce a single update count or result set, respectively.  If you need to execute multiple SQL statements in a single query, perhaps through a stored procedure call, then you should use Statement.execute() to execute the query and Statement.getMoreResults() to process all of the results.  However, in my not so humble opinion, the execute() and getMoreResults() methods aren’t exactly simple to use properly.  For example, execute() and getMoreResults() return false when the result is an update count.  But they also return false when there are no more results.  Ok, so how do you tell whether you have an update count or no more results?  You need to check the return value from a subsequent call to Statement.getUpdateCount() or Statement.getResultSet() .  One way to process all results (including errors) from a complex query would be to use code like this:



CallableStatement cs = con.prepareCall("{call myStoredProc()}");



int resultNum = 0;


while ( true )


{


boolean queryResult;


int rowsAffected;



if (1 == ++resultNum)


{


try


{


queryResult = cs.execute();


}


catch (SQLException e)


{


// Process the error


System. out .println("Result " + resultNum + " is an error: " + e.getMessage());



// When execute() throws an exception, it may just be that the first statement produced an error.


// Statements after the first one may have succeeded.  Continue processing results until there


// are no more.


continue ;


}


}


else


{


try


{


queryResult = cs.getMoreResults();


}


catch (SQLException e)


{


// Process the error


System. out .println("Result " + resultNum + " is an error: " + e.getMessage());



// When getMoreResults() throws an exception, it may just be that the current statement produced an error.


// Statements after that one may have succeeded.  Continue processing results until there


// are no more.


continue ;


}


}



if (queryResult)


{


ResultSet rs = cs.getResultSet();



// Process the ResultSet


System. out .println("Result " + resultNum + " is a ResultSet: " + rs);



rs.close();


}


else


{


rowsAffected = cs.getUpdateCount();



// No more results


if (-1 == rowsAffected)


{


--resultNum;


break ;


}



// Process the update count


System. out .println("Result " + resultNum + " is an update count: " + rowsAffected);


}


}



System. out .println("Done processing " + resultNum + " results");



Remember: to execute a complex query with a mix of DDL, DML and result sets, and possible errors, always use execute() to execute the query and use getUpdateCount(), getResultSet(), and getMoreResults() to process the results.



--David Olix [SQL Server]


This post is provided 'as is' and confers no express or implied warranties or rights.

%3CLINGO-SUB%20id%3D%22lingo-sub-383463%22%20slang%3D%22en-US%22%3EUse%20execute()%20and%20getMoreResults()%20methods%20for%20those%20pesky%20complex%20SQL%20queries%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-383463%22%20slang%3D%22en-US%22%3E%0A%20%26lt%3Bmeta%20http-equiv%3D%22Content-Type%22%20content%3D%22text%2Fhtml%3B%20charset%3DUTF-8%22%20%2F%26gt%3B%3CSTRONG%3E%20First%20published%20on%20MSDN%20on%20Aug%2001%2C%202008%20%3C%2FSTRONG%3E%20%3CBR%20%2F%3E%3CP%3EPer%20JDBC%20spec%2C%20the%20%3CA%20href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23executeUpdate(java.lang.String)%22%20mce_href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23executeUpdate(java.lang.String)%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3E%20Statement.executeUpdate()%20%3C%2FA%3E%20and%20%3CA%20href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23executeQuery(java.lang.String)%22%20mce_href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23executeQuery(java.lang.String)%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3E%20Statement.executeQuery()%20%3C%2FA%3E%20methods%26nbsp%3Bare%26nbsp%3Bto%20be%20used%20only%20with%20queries%20that%20produce%20a%20single%20update%20count%20or%20result%20set%2C%20respectively.%26nbsp%3B%20If%20you%20need%20to%26nbsp%3Bexecute%20multiple%20SQL%20statements%20in%20a%20single%20query%2C%20perhaps%26nbsp%3Bthrough%20a%20stored%20procedure%20call%2C%20then%20you%20should%20use%20%3CA%20href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23execute(java.lang.String)%22%20mce_href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23execute(java.lang.String)%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3E%20Statement.execute()%20%3C%2FA%3E%20to%20execute%20the%20query%20and%20%3CA%20href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23getMoreResults()%22%20mce_href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23getMoreResults()%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3E%20Statement.getMoreResults()%20%3C%2FA%3E%20to%20process%20all%20of%20the%20results.%26nbsp%3B%20However%2C%20in%20my%20not%20so%20humble%20opinion%2C%20the%20execute()%20and%20getMoreResults()%20methods%20aren%E2%80%99t%20exactly%20simple%20to%20use%26nbsp%3Bproperly.%26nbsp%3B%20For%20example%2C%20execute()%20and%20getMoreResults()%20return%20false%20when%20the%20result%20is%20an%20update%20count.%26nbsp%3B%20But%20they%20also%20return%20false%20when%20there%20are%20no%20more%20results.%26nbsp%3B%20Ok%2C%20so%20how%20do%20you%20tell%20whether%20you%20have%20an%20update%20count%20or%20no%20more%20results%3F%26nbsp%3B%20You%20need%20to%20check%20the%20return%20value%20from%20a%20subsequent%20call%20to%20%3CA%20href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23getUpdateCount()%22%20mce_href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23getUpdateCount()%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3E%20Statement.getUpdateCount()%20%3C%2FA%3E%20or%20%3CA%20href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23getResultSet()%22%20mce_href%3D%22http%3A%2F%2Fjava.sun.com%2Fjavase%2F6%2Fdocs%2Fapi%2Fjava%2Fsql%2FStatement.html%23getResultSet()%22%20target%3D%22_blank%22%20rel%3D%22nofollow%20noopener%20noreferrer%22%3E%20Statement.getResultSet()%20%3C%2FA%3E%20.%26nbsp%3B%20One%20way%20to%20process%20all%26nbsp%3Bresults%20(including%20errors)%20from%20a%20complex%20query%20would%20be%20to%20use%20code%20like%20this%3A%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3ECallableStatement%20cs%20%3D%20con.prepareCall(%22%7Bcall%20myStoredProc()%7D%22)%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Eint%20%3C%2FB%3E%20resultNum%20%3D%200%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Ewhile%20%3C%2FB%3E%20(%20%3CB%3E%20true%20%3C%2FB%3E%20)%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Eboolean%20%3C%2FB%3E%20queryResult%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Eint%20%3C%2FB%3E%20rowsAffected%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Eif%20%3C%2FB%3E%20(1%20%3D%3D%20%2B%2BresultNum)%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3E%20try%20%3C%2FB%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3EqueryResult%20%3D%20cs.execute()%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Ecatch%20%3C%2FB%3E%20(SQLException%20e)%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20Process%20the%20error%3C%2FP%3E%3CBR%20%2F%3E%3CP%3ESystem.%20%3CI%3Eout%20%3C%2FI%3E%20.println(%22Result%20%22%20%2B%20resultNum%20%2B%20%22%20is%20an%20error%3A%20%22%20%2B%20e.getMessage())%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20When%20execute()%20throws%20an%20exception%2C%20it%20may%20just%20be%20that%20the%20first%20statement%20produced%20an%20error.%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20Statements%20after%20the%20first%20one%20may%20have%20succeeded.%26nbsp%3B%20Continue%20processing%20results%20until%20there%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20are%20no%20more.%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Econtinue%20%3C%2FB%3E%20%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3E%20else%20%3C%2FB%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3E%20try%20%3C%2FB%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3EqueryResult%20%3D%20cs.getMoreResults()%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Ecatch%20%3C%2FB%3E%20(SQLException%20e)%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20Process%20the%20error%3C%2FP%3E%3CBR%20%2F%3E%3CP%3ESystem.%20%3CI%3Eout%20%3C%2FI%3E%20.println(%22Result%20%22%20%2B%20resultNum%20%2B%20%22%20is%20an%20error%3A%20%22%20%2B%20e.getMessage())%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20When%20getMoreResults()%20throws%20an%20exception%2C%20it%20may%20just%20be%20that%20the%20current%20statement%20produced%20an%20error.%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20Statements%20after%20that%20one%20may%20have%20succeeded.%26nbsp%3B%20Continue%20processing%20results%20until%20there%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20are%20no%20more.%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Econtinue%20%3C%2FB%3E%20%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Eif%20%3C%2FB%3E%20(queryResult)%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3EResultSet%20rs%20%3D%20cs.getResultSet()%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20Process%20the%20ResultSet%3C%2FP%3E%3CBR%20%2F%3E%3CP%3ESystem.%20%3CI%3Eout%20%3C%2FI%3E%20.println(%22Result%20%22%20%2B%20resultNum%20%2B%20%22%20is%20a%20ResultSet%3A%20%22%20%2B%20rs)%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3Ers.close()%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3E%20else%20%3C%2FB%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3ErowsAffected%20%3D%20cs.getUpdateCount()%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20No%20more%20results%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Eif%20%3C%2FB%3E%20(-1%20%3D%3D%20rowsAffected)%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E--resultNum%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3CB%3Ebreak%20%3C%2FB%3E%20%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%2F%2F%20Process%20the%20update%20count%3C%2FP%3E%3CBR%20%2F%3E%3CP%3ESystem.%20%3CI%3Eout%20%3C%2FI%3E%20.println(%22Result%20%22%20%2B%20resultNum%20%2B%20%22%20is%20an%20update%20count%3A%20%22%20%2B%20rowsAffected)%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%7D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3ESystem.%20%3CI%3Eout%20%3C%2FI%3E%20.println(%22Done%20processing%20%22%20%2B%20resultNum%20%2B%20%22%20results%22)%3B%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3ERemember%3A%26nbsp%3Bto%20execute%20a%20complex%20query%20with%20a%20mix%20of%20DDL%2C%20DML%20and%20result%20sets%2C%20and%20possible%20errors%2C%20always%20use%20execute()%20to%20execute%20the%20query%20and%20use%20getUpdateCount()%2C%20getResultSet()%2C%20and%20getMoreResults()%20to%20process%20the%20results.%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E%3C%2FP%3E%3CBR%20%2F%3E%3CP%3E--David%20Olix%20%5BSQL%20Server%5D%3C%2FP%3E%3CBR%20%2F%3E%3CP%3EThis%20post%20is%20provided%20'as%20is'%20and%20confers%20no%20express%20or%20implied%20warranties%20or%20rights.%3C%2FP%3E%0A%20%0A%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-383463%22%20slang%3D%22en-US%22%3EFirst%20published%20on%20MSDN%20on%20Aug%2001%2C%202008%20Per%20JDBC%20spec%2C%20the%20Statement.%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-383463%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3ESQLServerDrivers%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Version history
Last update:
‎Mar 23 2019 10:59 AM
Updated by: