I am a beginner in writing programs, I have created a search record function for my assignment.
public void searchRecord(){
for(int ct = 0; ct< 1; ct++){
System.out.println("Please insert student ID");
System.out.print("Student ID: ");//prompt for student ID to search
String data = k.nextLine().trim();
String sql = "SELECT * FROM Students WHERE StudentID = '"+data+"'";
try{
rs = st.executeQuery(sql);
if(rs.next()){
displayRecord();
rs.next();
showMenu();
}
else{
System.out.print("No record found. ");
ct--;
}
}catch (Exception ex){
System.out.println("Problem searching.");
}
}
However, after I try to get data from the result, it shows Invalid Cursor State.
If I want to retrieve data, I'll have to execute the Display next record method which is:
try{
if(rs.next()){
displayRecord();
}
else{
rs.previous();
System.out.println("No more records!");
}
}catch (Exception ex){
System.out.println("There is problem showing next data.");
}
I tried adding "rs.next" at the search record method after "displayRecord" but it wouldn't solve the problem. Is there anyway to solve this?
By the way my display record method:
public void displayRecord(){//get and display data from current row of record
try{
String ID = rs.getString(1);
String fname = rs.getString(2);
String lname = rs.getString(3);
String conNo = rs.getString(4);
String mail = rs.getString(5);
String plate = rs.getString(6);
Date date = rs.getDate(7);
System.out.print("Student ID: "+ID+"\nName: "+fname+" "+lname+"\nCar Number: "+plate+"\nContact Number: 0"+conNo+"\nE-Mail Address: "+mail+"\nDate Registered: "+date);
}catch (Exception ex){
System.out.println(ex);
}
}
Any helps or advices are appreciated.
I don't quite understand what your code is supposed to do. But I suspect you don't fully understand how JDBC statements and result sets work.
If you execute a query that returns many rows, you would write something like this:
ResultSet rs = stmt.executeQuery(sqlQuery);
while (rs.next()) {
String id = rs.getString(1);
String name = rs.getString(2);
// do something with the current row
}
Note that ResultSet instance allows you to access the data from the current result row. next() both advances to the next result row and tells you if there is next row (or whether you have advanced beyond the last row). Initially, it's positioned before the first result row. So next() needs to be called before accessing the first row's data. But that's all done in the single line while (rs.next()).
In your case, I would expect that the query only returns a single result row as the StudendID is most likely a unique key. So the code would look like this:
ResultSet rs = stmt.executeQuery(sqlQuery);
if (rs.next()) {
String id = rs.getString(1);
String name = rs.getString(2);
// do something with the current row
} else {
// no student with specified ID found
}
However, you code contains two calls to next() and another one to previous(), which is confusing.
There error message Invalid Cursor State indicates that you are trying to access the current row's data when in fact the result set is position before the start or after the end of the result set.
Related
now user come to my program and enter the name of any value,then i want to show the value.
System.out.println("enter name of item you want to order");
String userOrder = br.readLine();
Connection con = ConnectionToDB.connection();
String itemName= "select itemName from items";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(itemName);
while(rs.next())
{
if (rs.getString("itemName").equals(userOrder))
{
System.out.println(rs.getString("itemName"));
}
else
{
System.out.println("you order wrong item that not present");
}
}
when user enter 1st value that present in table that execute well and show the first values but when user input any other value that present in database but rs.next() is not working and else part executed. How can I overcome this?
Why you dont simply use:
"select itemName from items WHERE itemName = " + userOrder
This way you dont need iterate the result set you just:
if (rs.next()){
//Found
}
else {
//Not Found
}
Here's my code for the addStudent:
#FXML
private void addStudent(ActionEvent event) {
// sql query to insert data into students at ID, first name, last name, email and DOB
String sqlInsert = "INSERT INTO students(id,fname,lname,email,DOB) VALUES (?,?,?,?,?)";
try {
Connection conn = dbConnection.getConnection();
PreparedStatement stmt = conn.prepareStatement(sqlInsert);
// add the data in the right column
stmt.setString(1, this.id.getText());
stmt.setString(2, this.firstname.getText());
stmt.setString(3, this.lastname.getText());
stmt.setString(4, this.email.getText());
stmt.setString(5, this.dob.getEditor().getText());
stmt.execute();
conn.close();
} catch(SQLException ex) {
ex.printStackTrace();
}
}
And here's my code for removeStudent:
#FXML
private void removeStudent(ActionEvent event) {
try {
// sql query to delete data from the database
String sqlRemove = "DELETE FROM students WHERE id = ?";
// open a connection to the database and use PreparedStatement to
// initialize the query.
Connection conn = dbConnection.getConnection();
PreparedStatement delete = conn.prepareStatement(sqlRemove);
// information needed to delete the row
delete.setString(1, selectStudent());
// execute and delete
delete.executeUpdate();
// close the connection
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
// update table after deleting
loadStudentData(event);
}
The picture above is the view of my table. I hit LoadData and my table values show up. I want to be able to click on a row(student) and hit Delete Student to remove it.
Helper method for removeStudent:
private String selectStudent() {
String result = "";
try {
String sqlSelect = "SELECT id FROM students";
Connection conn = dbConnection.getConnection();
ResultSet rs = conn.createStatement().executeQuery(sqlSelect);
result = rs.getString(1);
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
return result;
}
I'm pretty sure it has to do with when I "click" on a row, the id value for that isn't being held anywhere so when I hit "Delete" nothing is being given for it to Delete.
I don't know. Any advice would be awesome. :D
First edit: nothing is assigned to delete.setString(1, this.id.getText()). When I click on the row and hit delete, nothing is happening because there's nothing being assigned to id when I click on the row. The query string DOES work however when I physically give it an ID to delete. Also verified that the button does work; it prints out a lovely message for me with a good ol' System.out.println("expletive");
Second edit: Ok, so I updated the removeStudent code and now all I get is the string "null" returned. Nothing deletes. Nothing updates. Nothing is happening except I get "null" in the console.
Third edit: Getting closer! With the realization that the removeStudent isn't being given an ID to delete, I decided to create a private helper method that will do a SELECT query. Now, when I hit delete, it'll delete....but from the top, and not at where I want it selected. The code is above.
Fourth edit: Getting even closer! So, I figured out how to capture the row I click on within the table and I can delete......however, because of my sqlRemove command, I'm deleting by id so if I click on a row with index 3, then ONLY the row within the table that has an id of 3 will be deleted, nothing else. I gotta re-write how the sqlRemove command is worded.
I fixed it:
private String selectStudent() {
// initial value for result to return
String result = "";
// grab the index of the row selected on the table
int initial = studenttable.getSelectionModel().getSelectedIndex();
try {
// SELECT query to execute
String sqlSelect = "SELECT id FROM students";
Connection conn = dbConnection.getConnection();
ResultSet rs = conn.createStatement().executeQuery(sqlSelect);
// while there's a next row
while(rs.next()) {
// set temp to equal the id rs.next() is currently on
String temp = rs.getString("id");
// get the row id - 1 since we start at 0
int temp1 = rs.getRow() - 1;
// if temp1 is equal to the index we selected
if(temp1 == initial) {
// make it equal to result
result = temp;
}
}
// close the connection
conn.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
// return the row to delete
return result;
}
What's going on is in the comments. I finally figured out how to pass the value from a selected row and compare it to a row. Once I get the correct row to pass, I give it to the delete function to remove.
After a day in a half.............but I love it, so. Yeah.
I have a strange problem. I have a database and I want to change the values of a column. The values are safed in an Arraylist (timelist).
In order to write the values in the right row, I have a second Arrylist (namelist). So I want to read the first row in my Database, than I check the namelist and find the name. Than i take the matching value out of the timelist and write it into the database into the column "follows_date" in the row, matching to the name.
And than I read the next row of the Database, until there are no more entries.
So the strange thing is, if I change nothing in the database, the while(rs.next()) part works.
For example:
ResultSet rs = statement.executeQuery("SELECT username FROM users");
while(rs.next()){
// read the result set
String name = rs.getString("username");
System.out.println("username = " + name); //liest die namen
}
}
This would print me every name after name. But when I change the table, the while loop ends after that. (no error, the program just finishes)
ResultSet rs = statement.executeQuery("SELECT username FROM users");
while(rs.next()){
// read the result set
String name = rs.getString("username");
System.out.println("username = " + name); //writes the name
//look, if name is in Arraylist "namelist"). if yes, than write the matching date from "timelist" into the database.
if (namelist.contains(name)){
System.out.println("name found: "+ name);
int listIndizi = namelist.indexOf(name); //get index
Long indiziDatum = (long) timelist.get(listIndizi); //get date from same Index
System.out.println(indiziDatum); // print date so i can see it is correct (which it is)
statement.executeUpdate("UPDATE users SET follows_date ="+ indiziDatum +" WHERE username = '"+name+"'"); //updates the follows_date column
}
}
Everything works fine, except that now, the while loop doesn't continues after the first passage, but ends.
The resultSet of a statement is closed and will not return further results if you execute another statement. Create a new separate statement object for the update and everything should work as excepted.
Statement statement1 = connection.createStatement();
Statement statement2 = connection.createStatement();
ResultSet resultSet1 = statement1.executeQuery("SELECT username FROM users");
while(resultSet1.next()){
...
statement2.executeUpdate("UPDATE users ..."));
}
As to Why it happens:
Here is the explanation from the official documentation:
A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
Alternative Approach:
From your sample, it seems you are trying to update the "same" row in your resultSet, you should consider using an Updatable ResultSet.
Sample code from the official documentation:
public void modifyPrices(float percentage) throws SQLException {
Statement stmt = null;
try {
stmt = con.createStatement();
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet uprs = stmt.executeQuery(
"SELECT * FROM " + dbName + ".COFFEES");
while (uprs.next()) {
float f = uprs.getFloat("PRICE");
uprs.updateFloat( "PRICE", f * percentage);
uprs.updateRow();
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
if (stmt != null) { stmt.close(); }
}
}
My current program can write data records in the database (also check if the primary key already exists). On the second step I want to extend my program with the feature that you are able to update/delete a dataset. UserID is the primary key. First name, Surname, Street aren't. But my aim is that you can also search for the first name or other fields, which arent primary, and get all dataset's where e.g. first name = searched value.
How I image it:
System.out.println("You have choosen edit/delete dataset!");
System.out.println("Enter UserID or other informations");
// Read in all available information from the user
//
UserInfo search = new UserInfo();
searchResult = search.getUserInfo(userid, firstname, secondname...);
The output on screen should like the following (Searched for Smith):
(1) ID0001 | Max | Smith | ....
(2) ID0002 | Justin | Smith | ...
And the user is able to choose the datset by input 1,2... which he want's to update or delete.
Problems which I dont know how to solve:
When the user haven't entered all information and just searched for eg. surname, how I can transmit the other empty fields, because the method expect also the other parameters.
When searchResult is an array, i haven't any reference to the database anymore, how I return the result back, without losing the reference to the database, that im still able to access on record.
EDIT: Using JDBC to connect to the database.
Use Scanner to get the user input, and search using this input:
System.out.println("You have choosen edit/delete dataset!");
System.out.println("Enter UserID or other informations");
Scanner scanner = new Scanner(System.in);
String searchKeyWord=scanner.next();
And then search using this keyword, or if you want to have many keywords you can use an array:
Scanner scanner = new Scanner(System.in);
String searchInput=scanner.next();
String[] keywords=searchInput.split(" ");
And then you can manage these keywords in your search like you want.
EDIT:
You can change your method so it will expect an array of keywords as an input, and whatever this array contains you will search using these keywords.
EDIT 2:
If he skips a value you can set it to null, and in your search method you only use the values that aren't null.
This is how your search method can be written to take all the parameters, and there you have to test all the cases whrer some fields can be null:
public void searchInfo(String[] keywords){
Connection conn = null;
Statement stmt = null;
try{
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(DB_URL, USER, PASS);
stmt = conn.createStatement();
String sql = "SELECT * FROM my_Table ";
if(keywords[0]!= null || keywords[1]!= null || keywords[2]!= null){
sql+=" WHERE ";
if(keywords[0]!= null){
sql+=" id= ?";
stmt.setInt(1, Integer.parseInt(keywords[0]));
if(keywords[1]!= null){
sql+="AND firstname= ? ";
stmt.setString(1, keywords[1]);
if(keywords[2]!= null){
sql+="AND secondname= ? ";
stmt.setString(2, keywords[2]);
}
}else if(keywords[2]!= null){
sql+="AND secondname= ? ";
stmt.setString(1, keywords[2]);
}
}else if(keywords[1]!= null){
sql+=" firstname= ? ";
stmt.setString(1, keywords[1]);
if(keywords[2]!= null){
sql+="AND secondname= ? ";
stmt.setString(2, keywords[2]);
}
}else if(keywords[2]!= null){
sql+=" secondname= ? ";
stmt.setString(1, keywords[2]);
}
}
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()){
//Retrieve by column name
int id = rs.getInt("id");
String first = rs.getString("firstname");
String second = rs.getString("secondname");
//Display values
System.out.print("ID: " + id);
System.out.print(", Firstname: " + first);
System.out.print(", Secondname: " + second);
}
rs.close();
}catch(SQLException se){
se.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(stmt!=null)
conn.close();
}catch(SQLException se){
}
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}//end try
}
EDIT 3:
//Let's say you got a list of User object List<User> ls
Iterator<User> it= ls.iterator();
int i=1;
while(it.hasnext()){
User u= (User) it.next();
System.out.println("("+i+") : ID= "+u.getId()+" Firstname= "+u.getFirstName()+" Secondname= "+ u.getSecondName);
i++;
}
System.out.println("Please enter the index of the wanted result:");
Scanner scan = new Scanner(System.in);
int index=scan.nextInt()-1; //index in list count from 0
if(index<=ls.size()){
System.out.println("the expected result is:");
System.out.println("ID= "+ls.get(index).getId()+" Firstname= "+ls.get(index).getFirstName()+" Secondname= "+ ls.get(index).getSecondName);
}
I have created one form, which contain information of user like name, contact no, photo id number, job profile etc. Once he enter all the information, it will store in database. When he login for second time, after entering photo id number whole information should display on the form, without he enters. I am using key typed event for this. I have tried this code, but it is throwing exception as
java.sql.SQLException: Before start of result set
public void show()
{
try
{
String id=photo_id_num.getText();
System.out.println(""+id);
Connect c=new Connect();
con=c.getConnection();
Statement stmt=con.createStatement();
String queryPhotoid = "select * from tbl_visitor ";
ResultSet rs1= stmt.executeQuery(queryPhotoid);
while (rs1.next())
{
if(id.equals(rs1.getString(6)))
{
// Read values using column name
String name = rs1.getString(2);
int contno = rs1.getInt(3);
String orgname = rs1.getString(4);
String jobpro = rs1.getString(5);
String category = rs1.getString(7);
String date = rs1.getString(8);
int noofpeople = rs1.getInt(9);
Blob image = rs1.getBlob(10);
int extrapeople = rs1.getInt(11);
System.out.println("Name:"+name+" Contact_no:"+contno+"Org_Name:"+orgname+" Job_profile:"+jobpro+"Category:"+category+"Date:"+date+"No_Of_People:"+noofpeople+"image:"+image+"Having extra people:"+extrapeople);
}
}
}
catch (SQLException sqlEx)
{
sqlEx.printStackTrace();
}
}
When you fetch result set the cursor is prior to the first record so you need to take cursor to the first record by executing resultSet.next(), Here in your case you are reading before positioning the cursor
System.out.println("ranu"+rs1.getString(6));
while (rs1.next());
So you first need to do rs.next() then only you can read the records
So make it as follows
ResultSet rs1= stmt.executeQuery(queryPhotoid);
while (rs1.next()) {
System.out.println("ranu"+rs1.getString(6));
if(id.equals(rs1.getString(6)))
{
// blah blah..
}
//blah
}