Rrugemalira
asked on
JDBC; JSP; mySQL; UPDATE: Failure to update record
The primary key is auto-incremented. I use result = ps.getGeneratedKeys(); to
obtain it and fail to update a record with the obtained primary key.
Here is the error message:
SQLException: Column not found, message from server: "Unknown column 'thePK' in 'where clause'"
SQLState: S0022
VendorError: 1054
Here is the table:
mysql> DESCRIBE patient;
+----------------+-------- ---------- ---+------ +-----+--- ------+--- ---------- ---+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------- ---------- ---+------ +-----+--- ------+--- ---------- ---+
| patient_id | bigint(20) unsigned | | PRI | NULL | auto_increment |
| address_id | bigint(20) unsigned | | PRI | 0 | |
| diagnosis_id | bigint(20) unsigned | | PRI | 0 | |
| sdp_id | bigint(20) unsigned | | PRI | 0 | |
| firstname | varchar(20) | YES | | NULL | |
| middlename | char(1) | YES | | NULL | |
| surname | varchar(20) | YES | | NULL | |
| date_birth | date | YES | | NULL | |
| gender | varchar(10) | YES | | NULL | |
| occupation | varchar(15) | YES | | NULL | |
| marital_status | varchar(10) | YES | | NULL | |
| num_dependants | int(11) | YES | | NULL | |
| patient_number | int(11) | YES | | NULL | |
+----------------+-------- ---------- ---+------ +-----+--- ------+--- ---------- ---+
13 rows in set (0.00 sec)
Here is the database handler: I'd appreciate answers also to comments marked Q: in the code
package patient.patientServlets;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.sql.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import patientBeans.PatientFormBe an;
public class DBHandlerPatient extends HttpServlet {
public void doPost (HttpServletRequest request,
HttpServletResponse response) {
try { // OBTAIN A DATABASE CONNECTION
// Step 1: Load the JDBC driver
Class.forName("com.mysql.j dbc.Driver ");
// Step 2: Establish a connection to the database
Connection conn = DriverManager.getConnectio n(
"jdbc:mysql://localhost/rt pmKenyaDB" ,"rmwijage ", "Psa23v1");
String sql = null;
sql = "INSERT INTO patient( patient_id, address_id, " +
"diagnosis_id, sdp_id, firstname, middlename, surname, " +
"date_birth, gender, occupation, marital_status, " +
"num_dependants, patient_number)" +
"VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
PreparedStatement ps = conn.prepareStatement(sql) ;
// Retreave bean properties to be inserted into table patient
PatientFormBean f = (PatientFormBean) request.getAttribute("form Handler");
String fname = f.getFirstName();
String mname = f.getMiddleName();
String lname = f.getLastName();
String birthdate = f.getDateOfBirth();
String theGender = f.getGender();
String theOccupation = f.getOccupation();
String theStatus = f.getMaritalStatus();
String theDependants = f.getNumOfDependants();
// Set the parameters in the prepared statement
ps.setNull(1,Types.BIGINT) ; // For PRIMARY KEY generation with auto increment!
ps.setInt(2, 0); // SQL BIGINT. Later to be given value from another table
ps.setInt(3, 0); // SQL BIGINT. = " =
ps.setInt(4, 0); // SQL MEDIUMINT = " =
ps.setString(5, fname);
ps.setString(6, mname);
ps.setString(7, lname);
ps.setString(8, birthdate);
ps.setString(9, theGender);
ps.setString(10, theOccupation);
ps.setString(11, theStatus);
ps.setString(12, theDependants);
ps.setInt(13, 0); // This value is to be updated shortly.
// Insert the row (record) into the table
int inserted = ps.executeUpdate(); // WORKS OK
System.out.println(inserte d); // Q: Can't see result in o/p window of NetBeans IDE. Why?
/* Query the database for the last inserted id. In this case,
* the value of patient_id hich was allocated automatically by
* the database
*/
// Q: Are the following lines OK for obtaining the generated Primary Key?
ResultSet result = null;
int thePK = -1;
result = ps.getGeneratedKeys();
if (result.next()) {
thePK = result.getInt(1);
}
else {
// throw an exception from here
}
System.out.println(thePK);
result.close();
// UPDATING row in table patient. I want to have patient_number = patient_id
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
ps = conn.prepareStatement(sql) ;
int update_count = ps.executeUpdate();
System.out.println(update_ count);
/* Later, I might want to have patient_number different from
* patient_id but derived from it.
*/
// Now close the connection
ps.close();
conn.close();
}
catch (SQLException e) {
// handle any errors
System.out.println("SQLExc eption: " + e.getMessage());
System.out.println("SQLSta te: " + e.getSQLState());
System.out.println("Vendor Error: " + e.getErrorCode());
}
catch (Exception e) {
e.printStackTrace();
}
// Send the request to rtpm_address.html
try {
getServletConfig().getServ letContext ().
// getRequestDispatcher("/suc cess_patie nt.jsp").
getRequestDispatcher("/suc cess_patie nt.jsp"). // later dispatch
forward(request, response); // to rtpm_address.html
}
catch (Exception e){}
}
}
// I do appreciate your expert advise. Thank you.
obtain it and fail to update a record with the obtained primary key.
Here is the error message:
SQLException: Column not found, message from server: "Unknown column 'thePK' in 'where clause'"
SQLState: S0022
VendorError: 1054
Here is the table:
mysql> DESCRIBE patient;
+----------------+--------
| Field | Type | Null | Key | Default | Extra |
+----------------+--------
| patient_id | bigint(20) unsigned | | PRI | NULL | auto_increment |
| address_id | bigint(20) unsigned | | PRI | 0 | |
| diagnosis_id | bigint(20) unsigned | | PRI | 0 | |
| sdp_id | bigint(20) unsigned | | PRI | 0 | |
| firstname | varchar(20) | YES | | NULL | |
| middlename | char(1) | YES | | NULL | |
| surname | varchar(20) | YES | | NULL | |
| date_birth | date | YES | | NULL | |
| gender | varchar(10) | YES | | NULL | |
| occupation | varchar(15) | YES | | NULL | |
| marital_status | varchar(10) | YES | | NULL | |
| num_dependants | int(11) | YES | | NULL | |
| patient_number | int(11) | YES | | NULL | |
+----------------+--------
13 rows in set (0.00 sec)
Here is the database handler: I'd appreciate answers also to comments marked Q: in the code
package patient.patientServlets;
import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.sql.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import patientBeans.PatientFormBe
public class DBHandlerPatient extends HttpServlet {
public void doPost (HttpServletRequest request,
HttpServletResponse response) {
try { // OBTAIN A DATABASE CONNECTION
// Step 1: Load the JDBC driver
Class.forName("com.mysql.j
// Step 2: Establish a connection to the database
Connection conn = DriverManager.getConnectio
"jdbc:mysql://localhost/rt
String sql = null;
sql = "INSERT INTO patient( patient_id, address_id, " +
"diagnosis_id, sdp_id, firstname, middlename, surname, " +
"date_birth, gender, occupation, marital_status, " +
"num_dependants, patient_number)" +
"VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
PreparedStatement ps = conn.prepareStatement(sql)
// Retreave bean properties to be inserted into table patient
PatientFormBean f = (PatientFormBean) request.getAttribute("form
String fname = f.getFirstName();
String mname = f.getMiddleName();
String lname = f.getLastName();
String birthdate = f.getDateOfBirth();
String theGender = f.getGender();
String theOccupation = f.getOccupation();
String theStatus = f.getMaritalStatus();
String theDependants = f.getNumOfDependants();
// Set the parameters in the prepared statement
ps.setNull(1,Types.BIGINT)
ps.setInt(2, 0); // SQL BIGINT. Later to be given value from another table
ps.setInt(3, 0); // SQL BIGINT. = " =
ps.setInt(4, 0); // SQL MEDIUMINT = " =
ps.setString(5, fname);
ps.setString(6, mname);
ps.setString(7, lname);
ps.setString(8, birthdate);
ps.setString(9, theGender);
ps.setString(10, theOccupation);
ps.setString(11, theStatus);
ps.setString(12, theDependants);
ps.setInt(13, 0); // This value is to be updated shortly.
// Insert the row (record) into the table
int inserted = ps.executeUpdate(); // WORKS OK
System.out.println(inserte
/* Query the database for the last inserted id. In this case,
* the value of patient_id hich was allocated automatically by
* the database
*/
// Q: Are the following lines OK for obtaining the generated Primary Key?
ResultSet result = null;
int thePK = -1;
result = ps.getGeneratedKeys();
if (result.next()) {
thePK = result.getInt(1);
}
else {
// throw an exception from here
}
System.out.println(thePK);
result.close();
// UPDATING row in table patient. I want to have patient_number = patient_id
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
ps = conn.prepareStatement(sql)
int update_count = ps.executeUpdate();
System.out.println(update_
/* Later, I might want to have patient_number different from
* patient_id but derived from it.
*/
// Now close the connection
ps.close();
conn.close();
}
catch (SQLException e) {
// handle any errors
System.out.println("SQLExc
System.out.println("SQLSta
System.out.println("Vendor
}
catch (Exception e) {
e.printStackTrace();
}
// Send the request to rtpm_address.html
try {
getServletConfig().getServ
// getRequestDispatcher("/suc
getRequestDispatcher("/suc
forward(request, response); // to rtpm_address.html
}
catch (Exception e){}
}
}
// I do appreciate your expert advise. Thank you.
you have an error in this line:
thePK has to be an int...
if you set "thePK" as an string it doesn't work, because then the variable thePK has no value
sql = new String("UPDATE patient SET patient_number = " + thePK+
"WHERE patient_id = " + thePK);
this should solve your problem!
original:
// UPDATING row in table patient. I want to have patient_number = patient_id
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
thePK has to be an int...
if you set "thePK" as an string it doesn't work, because then the variable thePK has no value
sql = new String("UPDATE patient SET patient_number = " + thePK+
"WHERE patient_id = " + thePK);
this should solve your problem!
original:
// UPDATING row in table patient. I want to have patient_number = patient_id
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
Q: Can't see result in o/p window of NetBeans IDE. Why?
I can't see why not, but try String.valueOf(inserted) and see what comes out.
// Q: Are the following lines OK for obtaining the generated Primary Key?
It looks ok. Are you getting the results you expected? is it returning the key? I had problems with this precise function not returning correct results just a month ago or so. I used the mysql function mentioned by Pat to get the keys.
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
Are you able to verify that the record is being writen? have you tried to execute the query from the phpadmin console or from the mysql interface directly? What is the exact error you get?
I can't see why not, but try String.valueOf(inserted) and see what comes out.
// Q: Are the following lines OK for obtaining the generated Primary Key?
It looks ok. Are you getting the results you expected? is it returning the key? I had problems with this precise function not returning correct results just a month ago or so. I used the mysql function mentioned by Pat to get the keys.
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
Are you able to verify that the record is being writen? have you tried to execute the query from the phpadmin console or from the mysql interface directly? What is the exact error you get?
I didn't notice the second question.
This code:
// UPDATING row in table patient. I want to have patient_number = patient_id
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
ps = conn.prepareStatement(sql) ;
int update_count = ps.executeUpdate();
System.out.println(update_ count);
should be changed too:
sql = new String("UPDATE patient SET patient_number = ? WHERE patient_id = ?");
ps = conn.prepareStatement(sql) ;
ps.setInt(1, thePK);
ps.setInt(2, thePK);
int update_count = ps.executeUpdate();
-Pat
This code:
// UPDATING row in table patient. I want to have patient_number = patient_id
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
ps = conn.prepareStatement(sql)
int update_count = ps.executeUpdate();
System.out.println(update_
should be changed too:
sql = new String("UPDATE patient SET patient_number = ? WHERE patient_id = ?");
ps = conn.prepareStatement(sql)
ps.setInt(1, thePK);
ps.setInt(2, thePK);
int update_count = ps.executeUpdate();
-Pat
// Insert the row (record) into the table
int inserted = ps.executeUpdate(); // WORKS OK
System.out.println(inserte d); // Q: Can't see result in o/p window of NetBeans IDE. Why?
I tried it on my eclipse console and i've got inserted = 1 as result.
but why you can't see it on your NetBeans IDE i don't know.
// Q: Are the following lines OK for obtaining the generated Primary Key?
ResultSet result = null;
int thePK = -1;
should work if you change the thePK as i mentioned :)
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
as i mentioned above: error with the sql String!
int inserted = ps.executeUpdate(); // WORKS OK
System.out.println(inserte
I tried it on my eclipse console and i've got inserted = 1 as result.
but why you can't see it on your NetBeans IDE i don't know.
// Q: Are the following lines OK for obtaining the generated Primary Key?
ResultSet result = null;
int thePK = -1;
should work if you change the thePK as i mentioned :)
// Q: According to error message, here is the culprit. But isn't patient_id = thePK?
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
as i mentioned above: error with the sql String!
ASKER
Yes, the problem was with:
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
Indeed, (and now I can say, obviously!) with:
sql = new String("UPDATE patient SET patient_number = " + thePK+
"WHERE patient_id = " + thePK);
the previous SQLException is removed. I thank you all.
From the o/p window of the IDE I see thePK = 22 (wasn't looking well enough!)
BUT THERE IS A NEW SQLException:
1
22
SQLException: Syntax error or access violation, message from server: "You have an error in your SQL syntax near 'patient_id = 22' at line 1"
SQLState: 42000
VendorError: 1064
Here is my latest code segment:
int thePK = -1;
ResultSet result = null;
result = ps.getGeneratedKeys();
if (result.next()) {
thePK = result.getInt(1);
}
else {
// throw an exception from here
}
System.out.println(thePK);
result.close();
sql = new String("UPDATE patient SET patient_number = " + thePK+
"WHERE patient_id = " + thePK);
ps = conn.prepareStatement(sql) ;
int update_count = ps.executeUpdate();
System.out.println(update_ count); // to check there was an update
// Now close the connection
ps.close();
conn.close();
Yes, I do check to see that the table is populated:
mysql> SELECT patient_id, patient_number FROM patient WHERE firstname="Johanna";
+------------+------------ ----+
| patient_id | patient_number |
+------------+------------ ----+
| 22 | 0 |
+------------+------------ ----+
1rows in set (0.00 sec)
patient_id != patient_number
sql = new String("UPDATE patient SET patient_number = thePK " +
"WHERE patient_id = thePK");
Indeed, (and now I can say, obviously!) with:
sql = new String("UPDATE patient SET patient_number = " + thePK+
"WHERE patient_id = " + thePK);
the previous SQLException is removed. I thank you all.
From the o/p window of the IDE I see thePK = 22 (wasn't looking well enough!)
BUT THERE IS A NEW SQLException:
1
22
SQLException: Syntax error or access violation, message from server: "You have an error in your SQL syntax near 'patient_id = 22' at line 1"
SQLState: 42000
VendorError: 1064
Here is my latest code segment:
int thePK = -1;
ResultSet result = null;
result = ps.getGeneratedKeys();
if (result.next()) {
thePK = result.getInt(1);
}
else {
// throw an exception from here
}
System.out.println(thePK);
result.close();
sql = new String("UPDATE patient SET patient_number = " + thePK+
"WHERE patient_id = " + thePK);
ps = conn.prepareStatement(sql)
int update_count = ps.executeUpdate();
System.out.println(update_
// Now close the connection
ps.close();
conn.close();
Yes, I do check to see that the table is populated:
mysql> SELECT patient_id, patient_number FROM patient WHERE firstname="Johanna";
+------------+------------
| patient_id | patient_number |
+------------+------------
| 22 | 0 |
+------------+------------
1rows in set (0.00 sec)
patient_id != patient_number
ASKER
I've also followed Pat's advice using code segment below:
BUT I get the SQLException:
1
SQLException: Before start of result set
SQLState: S1000
VendorError: 0
Here is the code segment:
Statement stmt = conn.createStatement();
ResultSet result = stmt.executeQuery("SELECT LAST_INSERT_ID() " +
"AS id FROM patient");
int thePK = -1;
thePK = result.getInt("id");
System.out.println(thePK);
result.close();
sql = new String("UPDATE patient SET patient_number = ? WHERE patient_id = ?");
ps = conn.prepareStatement(sql) ;
ps.setInt(1, thePK);
ps.setInt(2, thePK);
int update_count = ps.executeUpdate();
ps.close();
conn.close();
BUT I get the SQLException:
1
SQLException: Before start of result set
SQLState: S1000
VendorError: 0
Here is the code segment:
Statement stmt = conn.createStatement();
ResultSet result = stmt.executeQuery("SELECT LAST_INSERT_ID() " +
"AS id FROM patient");
int thePK = -1;
thePK = result.getInt("id");
System.out.println(thePK);
result.close();
sql = new String("UPDATE patient SET patient_number = ? WHERE patient_id = ?");
ps = conn.prepareStatement(sql)
ps.setInt(1, thePK);
ps.setInt(2, thePK);
int update_count = ps.executeUpdate();
ps.close();
conn.close();
look at pat5star answer.
> sql = new String("UPDATE patient SET patient_number = ? WHERE patient_id = ?");
> ps = conn.prepareStatement(sql) ;
> ps.setInt(1, thePK);
> ps.setInt(2, thePK);
> int update_count = ps.executeUpdate();
>
> -Pat
he uses a prepared Statement again.
try it and it should solve the problem.
greets, Manuel
> sql = new String("UPDATE patient SET patient_number = ? WHERE patient_id = ?");
> ps = conn.prepareStatement(sql)
> ps.setInt(1, thePK);
> ps.setInt(2, thePK);
> int update_count = ps.executeUpdate();
>
> -Pat
he uses a prepared Statement again.
try it and it should solve the problem.
greets, Manuel
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Oh, I'm sorry. I forgot you have to call rs.next() to move the cursor to the start of the resultSet. Change this code:
ResultSet result = stmt.executeQuery("SELECT LAST_INSERT_ID() " +
"AS id FROM patient");
int thePK = -1;
thePK = result.getInt("id");
to:
ResultSet result = stmt.executeQuery("SELECT LAST_INSERT_ID() " +
"AS id FROM patient");
int thePK = -1;
if (rs.next()) {
thePK = result.getInt("id");
} else {
// There was no result, which is a problem. Handle it somehow...
}
-Pat
ResultSet result = stmt.executeQuery("SELECT LAST_INSERT_ID() " +
"AS id FROM patient");
int thePK = -1;
thePK = result.getInt("id");
to:
ResultSet result = stmt.executeQuery("SELECT LAST_INSERT_ID() " +
"AS id FROM patient");
int thePK = -1;
if (rs.next()) {
thePK = result.getInt("id");
} else {
// There was no result, which is a problem. Handle it somehow...
}
-Pat
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I'd change your code:
// Q: Are the following lines OK for obtaining the generated Primary Key?
ResultSet result = null;
int thePK = -1;
result = ps.getGeneratedKeys();
if (result.next()) {
thePK = result.getInt(1);
}
else {
// throw an exception from here
}
System.out.println(thePK);
result.close();
to this:
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT LAST_INSERT_ID() AS id FROM patient");
thePK = rs.getInt("id");
That guarantees you will get the last inserted key of your primary key that was created with this connection. As long as you use the same connection to insert the data and then query for the LAST_INSERT_ID it is safe no matter how many concurrent inserts are being performed.
Hope that helps,
-Pat