How to find out if a Java ResultSet obtained is empty? - java

Class.forName("org.sqlite.JDBC");
Connection conn =
DriverManager.getConnection("jdbc:sqlite:userdata.db");
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("SELECT * from table WHERE is_query_processed = 0;");
int rowcount = rs.getRow();
System.out.println("Row count = "+rowcount); // output 1
rs.first(); // This statement generates an exception
Why is it so?

The pattern I normally use is as follows:
boolean empty = true;
while( rs.next() ) {
// ResultSet processing here
empty = false;
}
if( empty ) {
// Empty result set
}

Here's a simple method to do it:
public static boolean isResultSetEmpty(ResultSet resultSet) {
return !resultSet.first();
}
Caveats
This moves the cursor to the beginning. But if you just want to test whether it's empty, you probably haven't done anything with it yet anyways.
Alternatively
Use the first() method immediately, before doing any processing.
ResultSet rs = stat.executeQuery("SELECT * from table WHERE is_query_processed = 0;");
if(rs.first()) {
// there's stuff to do
} else {
// rs was empty
}
References
ResultSet (Java Platform SE 6)

You can do this too:
rs.last();
int numberOfRows = rs.getRow();
if(numberOfRows) {
rs.beforeFirst();
while(rs.next()) {
...
}
}

while (results.next())
is used to iterate over a result set.so results.next() will return false if its empty.

Why is execution not entering the
while loop?
If your ResultSet is empty the rs.next() method returns false and the body of the while loop isn't entered regardless to the rownumber (not count) rs.getRow() returns. Colins example works.

Shifting the cursor forth and back to determine the amount of rows is not the normal JDBC practice. The normal JDBC practice is to map the ResultSet to a List of value objects each representing a table row entity and then just use the List methods to determine if there are any rows.
For example:
List<User> users = userDAO.list();
if (users.isEmpty()) {
// It is empty!
if (users.size() == 1) {
// It has only one row!
} else {
// It has more than one row!
}
where the list() method look like as follows:
public List<User> list() throws SQLException {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
List<User> users = new ArrayList<User>();
try {
connection = database.getConnection();
statement = connection.createStatement();
resultSet = statement.executeQuery(SQL_LIST);
while (resultSet.next()) {
User user = new User();
user.setId(resultSet.getLong("id"));
user.setName(resultSet.getString("name"));
// ...
users.add(user);
}
} finally {
if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
return users;
}
Also see this answer for other JDBC examples.

CLOSE_CURSORS_AT_COMMIT
public static final int CLOSE_CURSORS_AT_COMMIT
The constant indicating that ResultSet objects should be closed when the method Connection.commit is called.

Try with this:
ResultSet MyResult = null;
MyResult = Conexion.createStatement().executeQuery("Your Query Here!!!");
MyResult.last();
int NumResut = MyResult.getRow();MyResult.beforeFirst();
//Follow with your other operations....
This manner you'll be able work normally.

This checks if it's empty or not while not skipping the first record
if (rs.first()) {
do {
// ResultSet is not empty, Iterate over it
} while (rs.next());
} else {
// ResultSet is empty
}

May be you can convert your resultset object into String object and check whether is it empty or not.
`if(resultset.toString().isEmpty()){
// containg null result
}
else{
//This conains the result you want
}`

Related

How to store output of MySQL command into a java variable (JDBC)

I was wondering how to issue a MySQL command that checks if a table within my database is empty and then subsequently store the boolean result into a java variable. I am trying to use JDBC commands to do this.
This is what I have so far but it is not working properly:
#Override
public boolean isEmpty(Connection connection) {
Statement statement = null;
ResultSet resultSet = null;
Boolean var = true;
try {
statement = connection.createStatement();
System.out.println(statement.execute("SELECT EXISTS (SELECT 1 FROM Persons) AS OUTPUT"));
if(statement.execute("SELECT EXISTS (SELECT 1 FROM Persons)")) {
var = false;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return var;
}
When I run the program with a completely new, unpopulated mySQL table, the function returns true. Does anyone know a solution?
Your test checks if the table exists, instead you want to see if the table contains any rows. In order to do so, select the count of rows from the table and verify it is greater than 0. Prefer PreparedStatement over Statement (it's more efficient and performant), and you need a ResultSet to actually iterate the result from the server. Something like,
#Override
public boolean isEmpty(Connection connection) {
PreparedStatement statement = null;
ResultSet resultSet = null;
boolean res = false; // no need for the wrapper type here.
String sql = "SELECT COUNT(*) FROM Persons";
try {
statement = connection.prepareStatement(sql);
System.out.println(sql);
resultSet = statement.executeQuery();
if (resultSet.next()) {
res = resultSet.getInt(1) > 0;
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return res;
}
Changed var to res because (as of Java 10) var is now a keyword in Java.
As you are executing a select statement, instead of using Statement.execute(..), you should use Statement.executeQuery(..) and iterate over its result set.
The boolean return value from execute(..) indicates if the first value is a result set or not. It is not the boolean column from your query. You should normally only use execute(..) if you don't know what type of statement it is, or if it is a statement that can produce multiple results (update counts and result sets).
So, instead use:
boolean exists;
try (ResultSet rs = statement.executeQuery("SELECT EXISTS (SELECT 1 FROM Persons)")) {
exists = rs.next() && rs.getBoolean(1);
}

Assign to string instead of resultset for jdbc query

I need to get the output of a jdbc query, but wherever I google, it returns a resultset. But, its just a single row. Here is my query
ResultSet rsLocationId = null;
rsLocationId = stmtLocation.executeQuery("SELECT apmcid FROM userbusinesstoapmc WHERE userbusinessid='"+userBusinessKey+"'");
It should return a single record as a string. How can I convert it? Any ideas would be greatly appreciated.
I suggest you use PreparedStatement and bind the parameter, currently you are vulnerable to SQL Injection attacks.
PreparedStatement ps = null;
ResultSet rs = null;
String result = null;
final String sql = "SELECT apmcid FROM userbusinesstoapmc "
+ "WHERE userbusinessid=?";
try {
ps = conn.prepareStatement(sql);
ps.setString(1, userBusinessKey);
rs = ps.executeQuery();
if (rs.next()) {
result = rs.getString("apmcid");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
you can try like this
ResultSet rsLocationId = null;String result="";
rsLocationId = stmtLocation.executeQuery("SELECT apmcid FROM userbusinesstoapmc WHERE userbusinessid='"+userBusinessKey+"'");
if(rsLocationId.next())
{
result=rsLocationId.getString('apmcid');
}
Even though your particular query only returns a single column, presumably some CHAR type if you expect the result to be a String, the executeQuery method returns a result set object, not a String object. So, you have to process the result set to get your String data. SpringLearner has provided a good example of how to do this.

Mysql Result set Error

I am executing a block of code where I need to retrieve a set of users from database and do some stuff with them. Very simple scenario.
The problem is that although I use while(rs.next()) , when rs.next() reaches null my program tries to continue with the code inside while clause and exits with Null Exception.
Why is that happening? Is something broken in my code that I cannot figure out?
Please, notice that rs is never null. At the beginning prints at the console all the contents of rs but when it reaches the end it returns null exception.
try {
String sql = "select distinct userid from userinfo";
stmt1 = conn.createStatement();
try (ResultSet rs = stmt1.executeQuery(sql)) {
while (rs.next()) {
String mentionsIDs = (rs.getString("mentions")).trim();
try{
if (!mentionsIDs.isEmpty() ){
System.out.println(mentionsIDs);
String[] arr = mentionsIDs.split("\\s+");
if(isNumeric(arr[0])){
System.out.println(arr[0]);
sources.add(Long.parseLong(arr[0]));
}
}
}
catch(Exception ex){
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
rs.close();
}
Any help is appreciated.
Move String mentionsIDs = (rs.getString("mentions")).trim(); inside the try block then catch NullPointerException.
You must also check that the result set indeed have some results in it. Put a condition over your while loop which checks that rs is not null.
if(rs!=null) {
while(rs.next()) {
... Process
}
} else {
System.out.println("The query returned 0 results");
}
In your code:
String sql = "select distinct userid from userinfo";
stmt1 = conn.createStatement();
try (ResultSet rs = stmt1.executeQuery(sql)) {
if(rs!=null) {
while (rs.next()){
String mentionsIDs = (rs.getString("mentions")).trim();
try{
if (!mentionsIDs.isEmpty() ){
System.out.println(mentionsIDs);
String[] arr = mentionsIDs.split("\\s+");
if(isNumeric(arr[0])){
System.out.println(arr[0]);
sources.add(Long.parseLong(arr[0]));
}
}
}
catch(Exception ex){
Logger.getLogger(App.class.getName()).log(Level.SEVERE, null, ex);
}
}
rs.close();
}

ResultSet is closed. Why?

I've got a small problem. I launch my application and after launching a query and comparing rs == null I get error ResultSet is closed.
Here is the code:
error_code = NO_ERROR;
try
{
ArrayList <Harmonogram> al = new ArrayList <Harmonogram> ();
ResultSet rs = stat.executeQuery(myQuery);
if (rs == null)
{
return null;
}else{
Harmonogram harm = new Harmonogram(rs.getLong(1), rs.getInt(2), rs.getInt(3), rs.getInt(4), rs.getLong(5), rs.getString(6));
After this I get a SQLException telling me: ResultSet is closed.
You are using incorrect method of checking whether ResultSet has any data.
Instead of
if ( rs == null )
{
return null;
}
use
if ( ! rs.next( ) )
{
return null;
}
The javadoc for PreparedStatement.executeQuery() says:
"Returns: a ResultSet object that contains the data produced by the query; never null"
The correct way to test for an empty ResultSet is to call ResultSet.hasNext().
Here's how I'd recommend that you write it:
public class HarmonogramDaoImpl implements HarmonogramDao {
private static final String FIND_ALL_SQL = "SELECT * FROM HARMONOGRAM ";
// inject this with either a constructor or setter
private Connection connection;
public List<Harmonogram> findAllHarmonograms() throws SQLException {
List<Harmonogram> harmonograms = new ArrayList<Harmonogram>();
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = this.connection.prepareStatement(FIND_ALL_SQL);
rs = ps.executeQuery();
while (rs.hasNext()) {
Harmonogram harm = new Harmonogram(rs.getLong(1), rs.getInt(2), rs.getInt(3), rs.getInt(4), rs.getLong(5), rs.getString(6));
harmonograms.add(harm);
}
} finally {
close(rs);
close(ps);
}
return harmonograms;
}
}
There are a few things left for you to do or guess, but this is a good start.
I would do something like
error_code = NO_ERROR;
try
{
ArrayList <Harmonogram> al = new ArrayList <Harmonogram> ();
ResultSet rs = stat.executeQuery(myQuery);
if (rs.next()){
Harmonogram harm = new Harmonogram(rs.getLong(1), rs.getInt(2), rs.getInt(3), rs.getInt(4), rs.getLong(5), rs.getString(6));
}else{
return null;
}
}Catch...
Or even while(rs.next()) if you're trying to loop over the resultSet (get all the records pulled from the database)

JDBC ResultSet closed statement

I'm trying to write a function that updates 2 tables in my database. I'm getting an error which i think is caused by calling next() on a resultset that has no more rows in the set.
I was thinking an if condition on hasNext() would fix this but it's not available to the result set...
The error i'm getting is 'No operations allowed after statement closed.'
private void updateDatabase() throws Exception {
Connection conn = getConnection();
PreparedStatement updateMovieStmt = conn.prepareStatement("INSERT INTO movies VALUES(null,?,null,null,null)", Statement.RETURN_GENERATED_KEYS);
PreparedStatement updateVideoStmt = conn.prepareStatement("INSERT INTO video_files VALUES(null,null,null,?,?)", Statement.RETURN_GENERATED_KEYS);
try {
for (Movie localMovie : getLocalMovies()) {
// fetch a local movie{
boolean newMovie = true;
for (Movie dbMovie : getDatabaseMovies(conn)) {
newMovie = true;
Pattern p = Pattern.compile(localMovie.getTitlePattern(), Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(dbMovie.getTitle());
// if it's already in the database not new movie... but is
// is it a new video rip????????????;
if (m.find()) {
System.out.println("DB movie: " + dbMovie.getTitle() + " matches localpattern of: " + localMovie.getTitlePattern());
newMovie = false;
break;
}
}
if (newMovie == true && localMovie.getTitle() != null) {
updateMovieStmt.setString(1, localMovie.getTitle());
updateMovieStmt.executeUpdate();
// get new movie id and put into new video row
ResultSet rs = updateMovieStmt.getGeneratedKeys();
if (rs.next()) {
updateVideoStmt.setBytes(1, localMovie.getHash());
updateVideoStmt.setInt(2, rs.getInt(1));
updateVideoStmt.executeUpdate();
}
}
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
updateMovieStmt.close();
updateVideoStmt.close();
conn.close();
}
}
If you're not using batches (addBatch()/executeBatch()), nor clearing the parameters (clearParameters()), then you should be creating the statements inside the loop, not outside the loop.
Move the both conn.prepareStatement() lines into the if (newMovie == true && localMovie.getTitle() != null) block, preferably refactored in separate methods. Your current method is doing way too much.
you can have only one open Statement per connection. Once you create a new Statement on the same connection, the previously created one will be closed
This holds true for resultSet that we can have only one resultSet open per statement. With a connection we can have multiple statements open.

Categories

Resources