This question already has answers here:
java.sql.SQLException: Illegal operation on empty result set. when authenticating
(2 answers)
Closed 2 years ago.
I'm trying to build a pay desk in a grocery store and my code actually performs what I intend for it to do, but for one thing.
After I ask the user to enter how many of an item they want, the product information is gathered and works fine, but when it's supposed to ask the user to enter product-ID for next product, the line is repeated and I get the following exception in my catch: "Illegal operation on empty result set". Again, all the calculations and everything is fine except for the repeating of that line. Any ideas on what might be the problem?
The output that is repeat is like this:
Enter product (or Exit):
ERROR1: Illegal operation on empty result set.
Enter product (or Exit):
And here's the code.
try {
Class.forName("com.mysql.jdbc.Driver");
String connection = "jdbc:mysql://myDB?";
connection = connection + "user=xxx&password=xxxxxx";
Connection conn = DriverManager.getConnection(connection);
// MATA IN PRODUKTNUMMER
System.out.println("\nEnter product (or Exit):");
GroceryStore.input = GroceryStore.scan.nextLine();
PreparedStatement stmt = conn.prepareStatement(
"SELECT * "+
"FROM Products "+
"WHERE productNo = ?");
stmt.setString(1, GroceryStore.input);
ResultSet rs = stmt.executeQuery();
rs.next();
pName = rs.getString("productName");
System.out.println("Product: " + pName);
// MATA IN ANTAL
System.out.println("\nEnter amount:");
GroceryStore.amount = GroceryStore.scan.nextInt();
pPrice = rs.getDouble("productPrice");
priceRounded = new BigDecimal(pPrice).setScale(2, BigDecimal.ROUND_FLOOR);
amountRounded = new BigDecimal(GroceryStore.amount).setScale(0);
priceRounded = priceRounded.multiply(amountRounded);
GroceryStore.sum = GroceryStore.sum.add(priceRounded);
inOut.output();
inOut.input();
conn.close();
}
catch (Exception e) {
System.out.println("ERROR1: " + e.getMessage());
}
You are not checking whether your result set has any data or row in it.
ResultSet rs = stmt.executeQuery();
rs.next();
...
...
You should check whether your result is empty or having any row:
ResultSet rs = stmt.executeQuery();
if(rs.next()){
.....
your code
.....
}
You haven't checked Whether your result set is empty or not before actually retriving values from Result set...
next() returns true if there is a data in the result set, false it there is not data at the a cursor position
Place your code like this
While(rs.next())
{
pName = rs.getString("productName");
System.out.println("Product: " + pName);
// MATA IN ANTAL
System.out.println("\nEnter amount:");
GroceryStore.amount = GroceryStore.scan.nextInt();
pPrice = rs.getDouble("productPrice");
}
Related
Im trying to get information in sql from database, there are two entries in each column but and with the following code, i am able to get the first entry information, if i wanted to get the second entry's records and display it also in project how would i get it?
String username1= rs.getString ("USERNAME");
String password1= rs.getString ("PASSWORD");
String aname1= rs.getString ("a_name");
String aname2= rs.getString ("a_name");
System.out.print("Enter Your Username: ");
String usernamea=(br.readLine());
System.out.print("Enter Your Password: ");
String passworda=(br.readLine());
if ((usernamea.equals(username1) && (passworda.equals(password1))))
{
System.out.println("Login Success! Welcome "+aname1+"!");
System.out.println("You are granted with Admin Acess!");
rs.close();
}
else if ((usernamea.equals(username2) && (passworda.equals(password2))))
{
System.out.println("Login Success! Welcome Guest User!");
rs.close();
}
I'm not quite sure what you are asking, nor am I sure how the code you posted actually relates to what you are asking.
When you say "you want the 2nd entry", I am assuming you mean the 2nd record in the SQL table.
try(Connection conn = DriverManager.getConnection(url, username, password)){
Statement stat = conn.createStatement();
ResultSet rs = stat.executeQuery("SELECT * FROM [TABLENAME]");
rs.next();
//All data stored in the ResultSet obj, to which you may loop through & select rows of interest. Particularly useful methods are .getMetaData(), .getRow(), etc.
}
Hopefully this is what you are asking for.
If you already have a ResultSet rs, you can call rs.next(). For Example some Code:
if (rs.next())
{
s.name = rs.getString(1);
s.creator = rs.getString(2);
s.dbname = rs.getString(3);
s.tsname = rs.getString(4);
s.cardf = rs.getFloat(5);
s.npages = rs.getInt(6);
s.statstime = rs.getString(7);
s.avgrowlen = rs.getInt(8);
}
Considering your code:
ResultSet rs = stat.executeQuery("SELECT * FROM [TABLENAME]");
String username1 = rs.getString ("USERNAME");
String password1 = rs.getString ("PASSWORD");
String aname1 = rs.getString ("a_name");
rs.next();
String username2 = rs.getString ("USERNAME");
String password2 = rs.getString ("PASSWORD");
String aname2 = rs.getString ("a_name");
Now you can check both the first entry and the second.
Nevertheless, the better practice is to create a user object, save username, password and aname in it.
Then, using some loop, you can go through the entire result set and get all the information from it.
ResultSet rs = stat.executeQuery("SELECT * FROM [TABLENAME]");
List<User> userList = new ArrayList<User>();
while(rs.next()) {
User user = new User();
user.setUsername(rs.getString ("USERNAME"));
user.setPassword(rs.getString ("PASSWORD"));
user.setAname(rs.getString ("a_name"));
userList.add(user);
}
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.)
I'm trying to make login code in java but there's some problem in my code.
If I enter correct data or wrong one still can't enter the loop to
go to next frame.
This is full code it's already have exception so it's not the problem .
Connection conn = null ;
try
{
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/DB?"+
"user=name&password=pass&characterEncoding=utf8");
String query = ("Select User_Name from user where User_Name = '" + txtUserName + "'
and password = '" + passwordField.getPassword().toString() + "' ; ");
PreparedStatement stmt = conn.prepareStatement(query);
ResultSet rs = stmt.executeQuery();
while (rs.wasNull()) {
System.out.println("true");
frame2.setVisible(true);
frame.setVisible(false);
break;
}
}
catch (SQLException ee)
{
JOptionPane.showMessageDialog(frame2, "Wrong inf ... please try again ");
}
I try this too but still not working.
Connection conn = null ;
try
{
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/DB?"+
"user=name&password=pass&characterEncoding=utf8");
PreparedStatement stmt = null;
String query = "Select User_Name from user where User_Name =? and password=?";
stmt = conn.prepareStatement(query);
stmt.setString(1, txtUserName.getText());
stmt.setString(2, passwordField.getPassword().toString());
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.println("true");
frame2.setVisible(true);
frame.setVisible(false);
break;
}
}
catch (SQLException ee)
{
JOptionPane.showMessageDialog(frame2, "Wrong inf ... please try again ");
}
I'm not really a Java programmer but a quick glance at your code and the descriptions of ResultSet::wasNull() ResultSet::next() show me you're misusing or misunderstanding how those work.
wasNull() tells you if the current column contains a null. An empty set is not null!
next() moves the cursor forward one row and returns true if the new current row is valid. False otherwise. In other words, if you have zero or one valid row, next() will immediately return false.
So, let's put things together.
Case 1: Using wasNull():
Enter valid data. ResultSet contains a non-null result. wasNull() returns false, don't enter while loop.
Enter invalid data. ResultSet contains an empty set result. wasNull() returns false, don't enter while loop.
Case 2: Using next():
Enter valid data. ResultSet contains a single non-null result. next() moves to next row [which is invalid] and returns false, don't enter while loop.
Enter invalid data. ResultSet contains a single empty set result. next() moves to next row [which is invalid] and returns false, don't enter while loop.
Might I suggest spending some time reading the ResultSet API documentation: https://docs.oracle.com/javase/7/docs/api/java/sql/ResultSet.html
public static void insertData() {
String insertFirstName;
String insertLastName;
int id;
Scanner in = new Scanner(System.in);
System.out.println("insert First Name: ");
insertFirstName = in.nextLine();
System.out.println("insert Last Name: ");
insertLastName = in.nextLine();
System.out.println("First name " + insertFirstName + " Last Name "
+ insertLastName);
try {
Statement statement = null;
Class.forName(JDBC_DRIVER);
Connection con = DriverManager.getConnection(DB_URL, "", "");
System.out.println("Connection Successfull");
statement = con.createStatement();
String sql = "Select id, FirstName, LastName FROM PhoneBook";
ResultSet rs = statement.executeQuery(sql);
rs.moveToInsertRow();
rs.next();
while (rs.next()) {
rs.updateString("FirstName", insertFirstName);
rs.updateString("LastName", insertLastName);
rs.insertRow();
}
statement.close();
rs.close();
} catch (Exception e) {
System.out
.println("********************ERROR*********************");
System.out.println(e.getMessage());
}
}
i KEEP getting
******************ERROR*******************
Invalid Cursor Type: 1003
and i dont understand why. i have RS.next() and then i go through the While(rs.next()). What am i doing wrong? Please help thank you
The javadoc of moveToInsertRow() says:
The insert row is a special row associated with an updatable result set
(emphasis mine)
The javadoc of ResultSet says:
A default ResultSet object is not updatable and has a cursor that moves forward only. Thus, you can iterate through it only once and only from the first row to the last row. It is possible to produce ResultSet objects that are scrollable and/or updatable. The following code fragment, in which con is a valid Connection object, illustrates how to make a result set that is scrollable and insensitive to updates by others, and that is updatable. See ResultSet fields for other options.
You need to open a updateable ResultSet:
statement = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE
);
See the documentation for ResultSet for further information.
Besides that, it looks like you might be moving a bit too far with the rs.next() calls after the rs.moveToInsertRow();. The example in the docs shows how you should do it:
rs.moveToInsertRow(); // moves cursor to the insert row
rs.updateString("FirstName", insertFirstName);
rs.updateString("LastName", insertLastName);
rs.insertRow();
So I'm very new to java and SQL and they are my first programming languages. I am trying to do some work with JDBC. I want to allow for a user to input an id and return a query based on the variable. If someone could at least point me in the right direction... Here is the code I'm starting with. Mind you its crude but just trying to get a working piece of code so I can better implement it in my main class.
Scanner input = new Scanner(System.in);
Class.forName("org.sqlite.JDBC");
Connection conn =
DriverManager.getConnection("jdbc:sqlite:C:\\Users\\Derek\\Documents\\Databases\\example.sqlite");
Statement stat = conn.createStatement();
PreparedStatement prep1 = conn.prepareStatement(
"insert into MedType values (?, ?);");
PreparedStatement prep2 = conn.prepareStatement(
"insert into Media values (?, ?,?, ?,?, ?);");
System.out.print("Please choose a database(MedType or Media): ");
String db=input.next();
if(db.equalsIgnoreCase("MedType"))
{
System.out.print("Enter in ID: ");
String answer1 = input.next();
System.out.print("");
String answer2 = input.nextLine();
System.out.print("Enter in Description: ");
String answer3 = input.nextLine();
prep1.setString(1, answer1);//add values into cell
prep1.setString(2, answer3);
prep1.addBatch();//add the columns that have been entered
}
conn.setAutoCommit(false);
prep1.executeBatch();
prep2.executeBatch();
conn.setAutoCommit(true);
System.out.print("Please Enter Query(One or All): ");
String q=input.next();
ResultSet rs= stat.executeQuery("select * from MedType;");
if(q.equalsIgnoreCase("all")){
while (rs.next()) {
System.out.print("All ID = " + rs.getString("ID") + " ");
System.out.println("All Description = " + rs.getString("Description"));}
}
if(q.equalsIgnoreCase("one")){
System.out.print("Enter ID: ");
}
int idNum=input.nextInt();
ResultSet oneRs = stat.executeQuery("select * from MedType Where"+ (rs.getString("ID")+"="+idNum));
if(q.equalsIgnoreCase("one")){
while (oneRs.next()) {
System.out.print("ID = " + oneRs.getString("ID") + " ");
System.out.println("Description = " + oneRs.getString("Description"));
}
}
rs.close();
oneRs.close();
conn.close();
}
}
ResultSet oneRs = stat.executeQuery("select * from MedType Where"+
(rs.getString("ID")+"="+idNum));
This is where I'm having trouble. Creating a statement that says return something from the table if its id is equal to the user input. I get this error
Exception in thread "main" java.sql.SQLException: [SQLITE_ERROR] SQL error or missing database (near "=": syntax error)
In query you are trying to access single row by passing id.. In generally sql query we are using to access single row by passing some information. select * from MedType where id=3 this query will return you result set containing row or rows with id equals to 3.
so in your code your query should be select * from MedType where id="+idNum+" if in your db id column is int.
and keep this query in if block only i.e
if(q.equalsIgnoreCase("one"))
{
System.out.print("Enter ID: ");
int idNum=input.nextInt();
ResultSet oneRs = stat.executeQuery("select * from MedType Where id="+idNum+" ");
// if id column in db is int if it is string then use id='"+idNum+"'
while (oneRs.next())
{
System.out.print("ID = " + oneRs.getString("ID") + " ");
System.out.println("Description = " + oneRs.getString("Description"));
}
}
In your query:
select * from MedType Where"+ (rs.getString("ID")+"="+idNum
you seem to try to grab the ID from the first resultset where you return all tuples.
That won't work as in the where clause the ID won't be there (as there is no result right now without rs.next()). If there was a result then you potentially have something like 'where 3 = 3' (3 would be the result of the previously returned value. Have you tried simply to use:
select * from MedType Where ID = " + idNum
Hope that makes sense.