Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I got a login system in java and i want to get de user, password and type of user from database. But when i run the programe i got the folowing error: java.sql.SLQException: Illegal operation on empty result set
Code:
conn=MysqlConnect.ConnectDB();
String Sql="Select*from utilizador where Nome='" + Username +"' and Password='" + Password +"' and Permissao'" + Permissao + "'" ;
try{
pst=conn.prepareStatement(Sql);
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(Sql);
int permissao = rs.getInt("Permissao");
String nome = rs.getString("Nome");
String password = rs.getString("Password");
if(rs.next()){
Your code has various issues:
You missed an = after and Permissao
From your code it seems you are looking for a user filtering by the following fields: Username, Password and Permissao, so you should have 3 variables defined
You are trying to access the ResultSet (using rs.getXXX) before selecting any rows. After the executeQuery method you "fill" a ResultSet but his index is not pointing to any valid "database rows" so you need to call "rs.next()" in order to move the index to the first row. Consecutive calls move the index ahead of 1 position every time until the ResultSet finishes.
Having said so, you should:
Use a prepared statement that prevents sql injection and other typo/character errors as it automatically escapes parameter values.
In the prepared statement use ? to define the parameters you'll need to set using s.set<TypeOfField>
Check if ResultSet has rows before using rs.get
Close connection, statement, and result set in the finally clause, so the resources will be closed either if there is or there is not an exception. Doing so you will prevent memory leak due to opened resources that you are not using anymore.
You should have 3 variable to perform the select: (I suppose)
Username of type String
Password of type String
Permissao of type int/Integer
Try using the following code, adapted to your needs.
Connection c = DB.dbConnect(null);
PreparedStatement s = null;
ResultSet rs = null;
try {
final String SQL = " Select * from utilizador where Nome=? and Password=? and Permissao = ? ";
s = c.prepareStatement(SQL);
int i = 1;
s.setString(i++, Username);
s.setString(i++, Password);
s.setInt(i++, Permissao);
rs = s.executeQuery();
if (rs.next()) {
int permissao = rs.getInt("Permissao");
String nome = rs.getString("Nome");
String password = rs.getString("Password");
}
} catch (SQLException e) {
// exception handler
} finally {
try {
if (rs != null)
rs.close();
} catch (Exception e) {
}
try {
if (s != null)
s.close();
} catch (Exception e) {
}try {
if (c != null)
c.close();
} catch (Exception e) {
}
}
Bad looking, unreadable code.
Here's your problem:
String nome = rs.getString("Nome");
String password = rs.getString("Password");
You try to access values from the ResultSet before checking to see if it has any rows.
Clearly the issue is with your query which is lacking proper quotes and spaces. It should be
String Sql="Select * from utilizador where Nome = '" + Username +"' and Password='" + Password +"' and Permissao = '" + Permissao + "'" ;
Related
I've got users trying to register to a site. before they can register their username of choice is searched for in an SQL database to make sure it doesn't already exist.
the problem is the names are never searched because the ResultSet always returns empty. I think it's the prepared statement.
I think my prepared statement isn't executing. I'm using executeQuery() to execute my statement because that's how I've been inserting the usernames without any problem. I got the search ResultsSet part if (rs.next())... from the method that inserts the usernames. Same with the String SQL and the prepared statement stuff.
String SQL = "SELECT * FROM users WHERE username='" + getUsername() + "'";
System.out.println(SQL);
// prints out SELECT * FROM users WHERE username='whatever I searched'
// so this String is valid
if (db.getConn() != null){
System.out.println("connected to database");
// always prints
}
PreparedStatement preparedStatement = db.getConn().prepareStatement(SQL);
// preparedStatement.setString(1, getUsername());
ResultSet rs = preparedStatement.executeQuery();
// userNameCounter = rs.getString("username");
// putting this here returns an sqlexception. empty set
if (preparedStatement != null){
System.out.println("ps != null");
// prints this
}
if (rs != null){
System.out.println("rs != null");
// prints this
}
if (!rs.next()){
System.out.println("!rs.next");
// prints this
}
if (rs.next()) {
userNameCounter = rs.getString("username");
System.out.println("rs.next()");
// doesn't print
// so the resultset is empty
if (!userNameCounter.equals(getUsername())) {
System.out.println("that username is unique");
return true;
}
}
preparedStatement.close();
incorrectLabels.setText("That username is already taken");
incorrectLabels.setVisible(true);
System.out.println("that username is already there");
// this always prints. it shouldn't
return false;
So executeUpdate() requires an int but I'm not sure what I would put there. And doing just execute() throws an error Requires ResultSet found boolean. I don't think there are any syntax errors since the table is called users. Everything I try just leads me back to an error resulting from an empty set. let me know if you need more code but this is where the error is happening.
Thanks!
You are issuing a query to the database when using the SELECT statement therefore you use the executeQuery() method.
What looks confusing is the userNameCounter variable you're using. Where is it declared and what is it declared as? It looks like it may be a Integer variable which would bring me to ask....what do you think the rs.getString("username") method returns?
As a matter of fact...what's with all the rs.next() conditions for all those if statements?
The whole thing is rather confusing. If you want to see if a User Name already exists within a database table then you might do it something like this:
if (db.getConn() == null){
throw new RuntimeException("Method Error! You Are NOT Connected To Database!");
}
String suppliedUserName = getUsername();
String dbUserName = "";
String SQL = "SELECT username FROM users WHERE username=?";
PreparedStatement preparedStatement = db.getConn().prepareStatement(SQL);
preparedStatement.setString(1, suppliedUserName);
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
dbUserName = rs.getString("username");
}
rs.close()
preparedStatement.close()
/* Below we use the equalsIgnoreCase() method. You
don't want a supplied User Name to be that close
or that similar to another User Name already in
Database. If you do then just use equals() method. */
if (dbUserName.equalsIgnoreCase(suppliedUserName)) {
System.out.println("The User name (" + suppliedUserName +
") is already in use. Try another User Name.");
return false;
}
else {
System.out.println("The User name (" + suppliedUserName + ") is Unique.");
return true;
}
Of course this code isn't tested and I assume you have your try/catch in place to handle any SQLException. I merely provide this code to give you an idea of how it can be accomplished.
I am using mySQL. As you see, the SQL statement is wrong at SELECT. So, I wonder what value the rs is?
I hope to get some advice. I thank you so much;
String sql = "SELCT * FROM user WHERE username = '" + username + "' and password = '" + password + "'";
ResultSet rs = stm.executeQuery(sql);
There would be no value because Statement.executeQuery(String) would throw a SQLException. As the linked Javadoc says,
Returns:
a ResultSet object that contains the data produced by the given query; never null
Throws:
SQLException - if a database access error occurs, this method is called on a closed Statement, the given SQL statement produces anything other than a single ResultSet object, the method is called on a PreparedStatement or CallableStatement
It will return you an exception having message like syntax error.
Easiest way to find is to debug your code by putting break points in code & examining / watching values of variables . Most IDEs have these debugging features. In addition to Elliott Frisch's answer, if I restructure your code like below then in case of invalid / incorrect SQL, control comes to catch block and you can see that value of rs remains null.
public void executeQuery(Connection conn, String username,String password) {
String sql = "SELCT * FROM user WHERE username = '" + username + "' and password = '" + password + "'";
ResultSet rs = null;
Statement stm = null;
try {
stm = conn.createStatement();
rs= stm.executeQuery(sql);
while(rs.next()) {
//Extract ResultSet here as per needed logic
}
} catch (SQLException e) {
// Your control comes here if query is wrong , put a break point at below line & examine value of rs
e.printStackTrace();
}finally {
// Close resources not needed after this method call like - result sets , statements & connection
}
}
Firstly statement won't execute, so next execution is depends on how you are going to handle that exception. So, if exception comes and if you handle also there will be null in ResultSet because no value assigned to it.
The user must choose a Resort ID from the table that is displayed and the make a booking. I can't seem to find my problem, I want to print the name of the Resort that they are making a booking at.
String x = jTextFieldID.getText();
Integer Resort = Integer.valueOf(x);
int resort = Integer.parseInt(x);
String sql = "SELECT RESORT_NAME FROM LouwDataBase.Resorts WHERE ID = "+Resort;
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, resort);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
String resortName = rs.getString("RESORT_NAME");
JOptionPane.showMessageDialog(null,
"You want to book at " + resortName);
}
You have to use rs.next() :
ResultSet rs = pstmt.executeQuery(sql);
String resortName = "";
if(rs.next()){//<<-----------------------------
resortName = rs.getString("RESORT_NAME");
}
JOptionPane.showMessageDialog(null, "You want to book at "+resortName);
If you want to get many results you can use while(rs.next){...} instead.
Note? for a good practice, don't use upper letter in beginning for the name of your variables ResortName use this instead resortName
You need to test over the ResultSet result before trying to read from it:
if(rs.next()) {
String ResortName = rs.getString(1);
JOptionPane.showMessageDialog(null, "You want to book at "+ResortName);
}
And you can use getString(1) to get the RESORT_NAME, check ResultSet .getString(int index) method for further details.
The error is that sql is passed to Statement.executeQuery(String) too, instead of the PreparedStatement.executeQuery().
int resort = Integer.parseInt(x);
//String sql = "SELECT RESORT_NAME FROM LouwDataBase.Resorts WHERE ID = ?";
String sql = "SELECT RESORT_NAME FROM LouwDataBase.Resorts WHERE ID = " + resort;
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
//pstmt.setInt(1, resort);
try (ResultSet rs = pstmt.executeQuery()) {
if (rs.next()) {
String resortName = rs.getString("RESORT_NAME");
JOptionPane.showMessageDialog(null,
"You want to book at " + resortName);
}
}
} catch (SQLException ex) {
Logger.getLogger(Booking.class.getName()).log(Level.SEVERE, null, ex);
}
Commented is the alternative usage of a prepared statement (as normally used).
Also you should close statement and result set, which can be done automatically with try-with-resources as above.
Oh, oversaw almost, that rs.next() must be called. (The others already mentioned.)
try {
ResultSet rs = stat.executeQuery("select * from details where COURSEANDDEPT='"+username+"'");
//if (rs.next()) {
while (rs.next()) {
String logid=rs.getString(1);
char temp=' ';
ResultSet ag=stat.executeQuery("select type from login");
if (ag.next()) {
temp=ag.getString(1).charAt(0);
if (temp=='s' || temp=='S') {
String logid=ag.getString(1);
stat.executeQuery("insert into assignments values('"+logid+"','"+comments+"','P','"+userid+"','"+username+"')");
}
}
}
JOptionPane.showMessageDialog(this,"Assignment Sent To The Whole Class");
//} else {
//JOptionPane.showMessageDialog(this,"Invalid Branch");
//}
} catch (ClassNotFoundException | SQLException ex) {
Logger.getLogger(Assignments.class.getName()).log(Level.SEVERE, null, ex);
}
The while loop of rs.next() terminates only in one iteration even after containing 6 records in itself. How to rectify it?
The problem is that you use the same statement object for executing several queries. Addictional problems are
you don't close neither your statements neither your resultsets (see example).
you should use statements' parameters (see example).
you should not use select *, but list the columns you want back from statement (i'll not include this in the example).
one of the queries ("select type from login") is always repeated the same way, maybe there's an error on the query. Otherwise it should be executed once outside the main loop.
in the example i don't manage the connection but this should be done too
Lets suppose that you have a Connection object called conn
PreparedStatemet stat=null;
PreparedStatement innerStat=null;
PreparedStatement insertStat=null;
try {
stat=conn.prepareStatement("select * from details where COURSEANDDEPT=?");
stat.setString(1,username);
ResultSet rs = stat.executeQuery();
//if (rs.next()) {
while (rs.next()) {
String logid=rs.getString(1);
char temp=' ';
innerStat=conn.prepareStatement("select type from login");
ResultSet ag=innerStat.executeQuery();
if (ag.next()) {
temp=ag.getString(1).charAt(0);
if (temp=='s' || temp=='S') {
String logid=ag.getString(1);
ag.close();
innerStat.close();
insertStat=conn.prepareStatement("insert into assignments values(?,?,?,?,?)");
insertStat.setString(1,logId);
insertStat.setString(2,comments);
insertStat.setString(3,"P");
insertStat.setString(4,userid);
insertStat.setString(5,username);
insertStat.executeUpdate();
insertStat.close();
}//closes if on temp
} //closes if on ag
} //closes while
rs.close();
stat.close();
JOptionPane.showMessageDialog(this,"Assignment Sent To The Whole Class");
//} else {
//JOptionPane.showMessageDialog(this,"Invalid Branch");
//}
} catch (ClassNotFoundException | SQLException ex) {
Logger.getLogger(Assignments.class.getName()).log(Level.SEVERE, null, ex);
if(insertStat!=null) insertStat.close();
if(innerStat!=null) innertStat.close();
if(stat!=null) stat.close();
}
Your problem is that each connection can only handle one SQL statement at a time. You're trying to leave your first select statement open while you do a bunch of other statements. You can't do this on a single connection.
I suggest two changes to make this work.
Do the query against the login table first. Its result won't vary from one iteration to the next, so there is no point in repeating it over and over within the main loop.
Rewrite the queries against details and assignments as an insert/select statement. It's probably something like the following.
.
"insert into assignments " +
"select logid, ,'" + comments + "','P','" + userid + "','" + username + "' "
"from details " +
"where COURSEANDDEPT='"+username+"'"
Also, you might consider writing this with a PreparedStatement, depending on whether SQL injection attacks are a likelihood.
m trying to loop through 3 resultsets and compare their values. bt its throwing this exception...could someone help me on where am going through?
here is the piece of code:
java.lang.Object[] reconciledPaymentDetails = null;
java.util.Vector shiftsVector = new java.util.Vector(1, 1);
String status = "";
try {
Class.forName("org.postgresql.Driver");
}
catch (ClassNotFoundException ex) {
Logger.getLogger(DBConnection.class.getName()).log(Level.SEVERE, null, ex);
}
try {
connDB = DriverManager.getConnection("jdbc:postgresql://" + hostName + ":" + portNumber + "/" + dbName, userName, password);
System.out.println("Connection established : [" + connDB.toString() + "]");
java.sql.Statement pstmt = connDB.createStatement();
java.sql.Statement pstmtShifts = connDB.createStatement();
java.sql.ResultSet rset = pstmt.executeQuery("SELECT DISTINCT payment_mode,transaction_type, credit FROM ac_cash_collection WHERE shift_no = '" + shiftNumber + "'");
while (rset.next()) {
java.sql.ResultSet rsetShifts = pstmtShifts.executeQuery("SELECT DISTINCT amount, shift_amount FROM ac_shift_collections WHERE shift_no = '" + shiftNumber + "' AND pay_mode ilike '"+rset.getString(1) +"'");
while (rsetShifts.next()) {
java.sql.ResultSet rset2 = pstmt.executeQuery("select debit from ac_cash_book where shift_no='"+shiftNumber+"'");
while (rset2.next()){
double debit =rset2.getDouble("debit");
if((rset2.getDouble("debit")<=0 ))
status = "no_banked";
else if((rset2.getDouble("debit")==rsetShifts.getDouble("amount"))
&& (rsetShifts.getDouble("amount"))< rsetShifts.getDouble("shift_amount"))
status= "BntClosed";
else if (rset2.getDouble(1)==rsetShifts.getDouble("shift_amount"))
status ="bClosed";
shiftsVector.addElement(rset.getString(1)+":"+rsetShifts.getString(1)+":"+status);
}
}
}
The documentation provides a clear explanation of this:
By default, only one ResultSet object per Statement object can be open
at the same time. Therefore, if the reading of one ResultSet object is
interleaved with the reading of another, each must have been generated
by different Statement objects. All execution methods in the Statement
interface implicitly close a statment's current ResultSet object if an
open one exists.
So your options would be:
Use a different Statement instance for each query.
Collect all the results from each ResultSet (i.e. into a Set or a List) before moving on to the next one, and then run the comparison on the collected results instead of directly on the result-sets.