简体   繁体   中英

java.sql.SQLException: Illegal operation on empty result set. when authenticating

What I'm trying to do is:

  1. Accept username(uname) and password(passw) as an input from the user.

  2. Using ResultSet , retrieve the only tuple, to which username in the database and username given by user suits. This tuple will contain username and password.

  3. If the password given by user also suits the password in the database, the display the message that both creadentials are correct else one of them is wrong.

Everything works fine except in one case. When the username itself is wrong, the mysql will not find the attribute at all and will give this error: java.sql.SQLException: Illegal operation on empty result set.

The code is:

ok.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent ae)
        {
            String uname=jf1.getText();
            String passw=jf2.getText();
            String n;
            String m;
            try
            {
                Class.forName("com.mysql.jdbc.Driver").newInstance();
                Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/authentication?" + "user=root&password=letmein");
                PreparedStatement stmt=conn.prepareStatement("Select * from admin where id = ?");
                stmt.setString(1,uname);
                ResultSet rs=stmt.executeQuery();
                rs.next();
                n=rs.getString("id");
                m=rs.getString("pass");
                conn.close();
                if(n.equalsIgnoreCase(uname) && m.equalsIgnoreCase(passw))
                {
                    JOptionPane.showMessageDialog(null,"Username and password is correct");
                }
                else
                {
                    JOptionPane.showMessageDialog(null,"Username or password is not correct");
                }

            }
            catch(Exception ex)
            {
                  System.out.println(ex);
            }
        }//end of actionperformed
    });//end of actionlistener

Is there any way I can do both operations at a time (before closing the connection with database)?. If not, what's the alternative method?

You are supposed to use the result of rs.next() :

            if (rs.next()) {
                n=rs.getString("id");
                m=rs.getString("pass");
            }

If rs.next() returns false, this means the query returned no rows.

@Eran mentioned the error by which a wrong id would yield an empty result set on which fields were gotten.

I still have small remarks:

  • Try-with-resources take care of closing even in case of an exception or returning.
  • For a local database you can send the password to SQL.
  • Best to store passwords encrypted , when ever your database should get stolen.

Thus:

boolean loggedIn = false;
try (PreparedStatement stmt =
        conn.prepareStatement("SELECT 1 FROM admin WHERE id = ? AND pass = PASSWORD(?)")) {
    stmt.setString(1, uname);
    stmt.setString(2, passw);
    try (ResultSet rs = stmt.executeQuery()) {
         loggedIn = rs.next();
    } // Closes rs.
} // Closes stmt.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM