Adding values to database table only once - java

I have to create a cart application in Spring MVC.
I have this cartentries table in database, where I store book_id,id_cartEntry and other fields. Also I have an user table, where I store id_user. I have similar entries in my cartentries, and when I click the checkout button, those entries have to be loaded into a cart table.
The problem is that I don't know how to store the id_user field into a variable, so that I do not have to have this line of code:
while (resultSet2.next())
This is making my code execute only once, so that only one entry from cartentries is loaded into the cart table. This is because the resultSet2 doesn't find any more new users in the table, because I am logged into a single user. How can I make all data from cartentries go into cart table?
This is the function:
#RequestMapping("/checkout")
public void checkout(#RequestParam String username) {
System.out.println("this is checkout from book controller");
System.out.println("username is " + username);
Connection connection = ConnectToDatabase.createConnection();
try {
PreparedStatement preparedStatement = connection.prepareStatement("select * from cartentries");
ResultSet resultSet = preparedStatement.executeQuery();
PreparedStatement preparedStatement2 = connection.prepareStatement("select id_user from user where username='" + username + "'");
ResultSet resultSet2 = preparedStatement2.executeQuery();
while (resultSet.next()) {
while (resultSet2.next()) {
PreparedStatement preparedStatement1 = connection.prepareStatement("INSERT INTO cart(id_user,id_cartEntry,totalPrice)VALUES(?,?,?)");
preparedStatement1.setInt(1,resultSet2.getInt("id_user"));
preparedStatement1.setInt(2, resultSet.getInt("id_cartEntry"));
preparedStatement1.setInt(3, resultSet.getInt("totalPrice"));
preparedStatement1.executeUpdate();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

I've change your code to "store" the userid if it was found.
try {
PreparedStatement preparedStatement = connection.prepareStatement("select * from cartentries");
ResultSet resultSet = preparedStatement.executeQuery();
PreparedStatement preparedStatement2 = connection.prepareStatement("select id_user from user where username=?");
preparedStatement2.setString(1, username);
ResultSet resultSet2 = preparedStatement2.executeQuery();
PreparedStatement preparedStatement1 = connection.prepareStatement("INSERT INTO cart(id_user,id_cartEntry,totalPrice)VALUES(?,?,?)");
Integer userId;
if (resultSet2.next()) {
// guess it found at least one user
userId = resultSet2.getInt("id_user");
}
if (userId != null) {
while (resultSet.next()) {
preparedStatement1.setInt(1, userId);
preparedStatement1.setInt(2, resultSet.getInt("id_cartEntry"));
preparedStatement1.setInt(3, resultSet.getInt("totalPrice"));
preparedStatement1.executeUpdate();
}
}
} catch (Exception e) {
e.printStackTrace();
}
I've also change your userid query to use setString instead of concatenation. See SQLInjection
Maybe you can refactor those statements into separated methods for better code reading.
PS. Don't forget to add a finally clause and close the connection (or the try-with-resources) to prevent having a resource leaking on database server.

Related

How to copy data from one table to another and then delete that data in first table using Java?

Two tables are present in the database, one is Student table with columns roll_no(PK), name, grade and DOB, another table StudentLeft with columns roll_no, name, grade and leaving_date.
I want to delete the record of the student from Student table whose roll no is entered by the user, and add the roll no, name, grade and leaving_date (the date when the record is deleted and added to the table) to StudentLeft table.
This is my method.
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null, preparedStatement1 = null, preparedStatement2 = null;
ResultSet resultSet = null;
String selectQuery = "", updateQuery = "", deleteQuery = "";
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
connection = dataSource.getConnection();
}
catch (ClassNotFoundException e) {
e.printStackTrace();
}
catch (SQLException e) {
e.printStackTrace();
}
int rollNo = Integer.parseInt(args[0]);
try {
selectQuery = "SELECT name, grade FROM Student WHERE roll_no = ?";
updateQuery = "INSERT INTO StudentLog values WHERE roll_no = ?, name = ?, standard = ?";
deleteQuery = "DELETE Student WHERE roll_no = ?";
connection.setAutoCommit(false);
preparedStatement = connection.prepareStatement(selectQuery);
preparedStatement.setInt(1, rollNo);
resultSet = preparedStatement.executeQuery();
preparedStatement1 = connection.prepareStatement(updateQuery);
preparedStatement1.setInt(1, rollNo);
while (resultSet.next()) {
String name = resultSet.getString("name");
String grade = resultSet.getString("grade");
preparedStatement1.setString(2, name);
preparedStatement1.setString(3, grade);
preparedStatement1.addBatch();
}
preparedStatement1.executeBatch();
preparedStatement2 = connection.prepareStatement(deleteQuery);
preparedStatement.setInt(1, rollNo);
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
}
try {
if (!preparedStatement.isClosed() || !preparedStatement1.isClosed() || !preparedStatement2.isClosed()) {
preparedStatement.close();
preparedStatement1.close();
preparedStatement2.close();
}
if (!connection.isClosed())
connection.close();
}
catch (SQLException e) {
e.printStackTrace();
}
}
These are the errors.
java.sql.BatchUpdateException: ORA-00936: missing expression
at oracle.jdbc.driver.OraclePreparedStatement.executeBatch(OraclePreparedStatement.java:10500)
at oracle.jdbc.driver.OracleStatementWrapper.executeBatch(OracleStatementWrapper.java:230)
at Q3.main(Q3.java:48)
Exception in thread "main" java.lang.NullPointerException
at Q3.main(Q3.java:62)
I am using oracle 11g express database.
The code you've written can be simplified quite a bit:
public static void main(String[] args) {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e) {
e.printStackTrace();
return;
}
int rollNo = Integer.parseInt(args[0]);
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);
String transferStatement = "INSERT INTO StudentLog (roll_no, name, standard, leaving_date) " +
"SELECT roll_no, name, standard, SYSDATE FROM Student WHERE roll_no = ?";
try (PreparedStatement stmt = connection.prepareStatement(transferStatement)) {
stmt.setInt(1, rollNo);
stmt.executeUpdate();
}
String deleteStatement = "DELETE FROM Student WHERE roll_no = ?";
try (PreparedStatement stmt = connection.prepareStatement(deleteStatement)) {
stmt.setInt(1, rollNo);
stmt.executeUpdate();
}
connection.commit();
}
catch (SQLException e) {
e.printStackTrace();
}
}
I've used try-with-resources statements, which simplifies the clean-up of connections and prepared statements: the connection and statements will get closed when the code inside the try (...) block finishes executing.
Transferring data from the Student table to the StudentLog table can be done in one go with an INSERT INTO ... SELECT statement. This statement doesn't return any result set: there's nothing to iterate through, we just execute it and the row gets inserted.
The DELETE statement is similar: it too returns no result set. I've added the keyword FROM to it out of convention more than anything else: as pointed out on another answer, FROM is optional.
I've also moved the catch (SQLException e) block to the end: that will handle all SQLExceptions generated when connecting to the database or executing either of the prepared statements.
I've kept the code that attempts to load the Oracle database driver class, but added a return statement in the catch block: if there's an exception, the driver isn't on the classpath and connecting to the database is guaranteed to fail so we may as well stop. However, for recent versions of the Oracle driver you don't need this check. Experiment with it: see if the code works without this check and if so, remove it.
Shouldn't your query be
DELETE FROM Student WHERE roll_no = ?
instead of
DELETE Student WHERE roll_no = ?
Your DELETE code used the wrong prepared statement, missing an execute.
It is advisable to use try-with-resources as below, for the automatic closing,
even on return or exception. (It also takes care of variable scopes.)
public static void main(String[] args) throws SQLException {
int rollNo = Integer.parseInt(args[0]);
// Better statements possible.
final String selectQuery = "SELECT name, grade FROM Student WHERE roll_no = ?";
final String updateQuery =
"INSERT INTO StudentLog VALUES WHERE roll_no = ?, name = ?, standard = ?";
final String deleteQuery = "DELETE FROM Student WHERE roll_no = ?";
try { // Check whether you need this. It is for the old discovery mechanism.
Class.forName("oracle.jdbc.driver.OracleDriver");
}
catch (ClassNotFoundException e) {
throw new IllegalStateException("Database driver not provided", e);
}
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);
try (PreparedStatement preparedStatement =
connection.prepareStatement(selectQuery)) {
preparedStatement.setInt(1, rollNo);
try (ResultSet resultSet = preparedStatement.executeQuery()) {
try (PreparedStatement preparedStatement1 =
connection.prepareStatement(updateQuery)) {
preparedStatement1.setInt(1, rollNo);
while (resultSet.next()) {
String name = resultSet.getString("name");
String grade = resultSet.getString("grade");
preparedStatement1.setString(2, name);
preparedStatement1.setString(3, grade);
preparedStatement1.addBatch();
}
preparedStatement1.executeBatch();
}
}
}
try (PreparedStatement preparedStatement2 =
connection.prepareStatement(deleteQuery)) {
preparedStatement2.setInt(1, rollNo); // NOT preparedStatement
preparedStatement2.executeUpdate();
}
connection.commit();
}
}
Then one should SELECT+INSERT to the database, using one statement (INSERT SELECT).
The SQL of the StudentLog is a bit incomprehensible to me, but a nice INSERT would be:
INSERT INTO StudentLog VALUES(roll_no, name, standard)
SELECT roll_no, name, grade
FROM Student
WHERE roll_no = ?
Removing the need java nesting of database accesses.

Insert query not executing

I want to insert the product the user selected into a table called cart which has two columns: cart_id and item_id_FK both are foreign keys. User_id and id are passed in the constructor and then inserted into cart_id and item_id_fk.
No errors are showing in the code, I double checked the connection username and password, everything works fine except for the cart table.
I tried putting a try and catch statement inside and repeating the steps it didn't work.
if (e.getSource()==AddToCartBtn)
{
//Check to see if item is available
String SizeSelection;
SizeSelection = SizeCmbx.getSelectedItem().toString();
String DBURL ="JDBC:MySql://localhost:3306/shoponline?useSSL=true";
String USER ="root";
String PASSWORD ="12345678";
try {
Connection con = DriverManager.getConnection(DBURL, USER, PASSWORD);
String sql2 = String.format("select itemid,size,productid_fk from items where size='%s' and productid_fk=%d",SizeSelection,id);
PreparedStatement statement = con.prepareStatement(sql2);
ResultSet result = statement.executeQuery(sql2);
String sql3 = "insert into cart (CartID, ItemID_FK)" + " values (?, ?)";
PreparedStatement preparedStmt = con.prepareStatement(sql3);
preparedStmt.setInt(1, user_ID);
preparedStmt.setInt(2, id);
if(result.next())
{
//if item is available
// execute the preparedstatement
preparedStmt.execute();
}//end if
con.close();
}// end try
catch (SQLException ex){
ex.printStackTrace();
}//end catch
Change executeQuery to executeUpdate:
executeQuery(sql3)
to
executeUpdate(sql3)
I believe integers don't need the ' ' around them to be inserted, you may try removing those as well. It may be mistaking them as characters or something similiar.
Otherwise if neither of those above fixes work, try something like this:
String query = "insert into cart (CartID, ItemID_FK)"
+ " values (?, ?)";
// create the mysql insert preparedstatement
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setInt(1, xInt);
preparedStmt.setInt(2, yInt);
// execute the preparedstatement
preparedStmt.execute();
conn.close();

How to write a single query for multiple data manipulation in mysql?

I have to insert values from jsp form to database table and to the same table I need to insert values for two columns from 2 different tables.
Here is the code:
public class ForgotPassWordDAO {
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
public void createSecretQnA(ForgotPassWord forgotPassWord) {
String sql = "INSERT INTO forgotpassword (PwdId,SecretQuestion1,SecretAnswer1,SecretQuestion2,SecretAnswer2)VALUES(?,?,?,?,?)"; // Here am inserting form values to database.
String sql1="INSERT INTO forgotpassword (CustId) SELECT CustId FROM signup";// Here am trying to get value from another table and insert
String sql2="INSERT INTO forgotpassword (LoginId) SELECT LoginId FROM login"; // Here am trying to get value from another table and insert
Connection conn = null;
try {
conn = dataSource.createConnection();
PreparedStatement ps = conn.prepareStatement(sql);
PreparedStatement ps1 = conn.prepareStatement(sql1);
PreparedStatement ps2 = conn.prepareStatement(sql2);
ps.setInt(1, forgotPassWord.getId());
ps.setString(2, forgotPassWord.getSq1());
ps.setString(3, forgotPassWord.getAnSq1());
ps.setString(4, forgotPassWord.getSq2());
ps.setString(5, forgotPassWord.getAnSq2());
ps.executeUpdate();
ps1.executeUpdate();
ps2.executeUpdate();
ps.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
catch (NullPointerException e1){
}
finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
}
}
}
}
But on each executeUpdate() its incrementing and the values from the form are stored in one row and in the next row the values from the signup and login tables are getting stored. How to make all this get stored in a single row? Any help is appreciated.
You are doing 3 inserts, so at least 3 rows are created. Also, when you do SELECT CustId FROM signup, how can you ensure that only one and the right value of CustId is taken from signup table? With this query you are fetching all the CustId. Same goes for login table and query.
To merely resolve your problem you have to create a single query:
String sql = "INSERT INTO forgotpassword (PwdId,SecretQuestion1,SecretAnswer1,SecretQuestion2,SecretAnswer2,CustId,LoginId)VALUES(?,?,?,?,?,(SELECT CustId FROM signup),(SELECT LoginId FROM login))";
^ ^ ^ ^
but I don't think you have thought this enough.
There should be something like:
SELECT LoginId FROM login WHERE CustId=? //Here I'm guessing, I don't know your tables.
The point is to get the correct value both in login table and signup table that corresponds to the user who forgot his password. This can be easily done with a WHERE clause (supposing your foreign key are setted correctly).
EDIT
As per your comment I'm going to clarify the way you should add your new user.
First of all you need to create the new user, so as soon as the information needed is sent and checked you insert a new row in signup table. But wait to execute the query.
You need the CustId. Because is an auto-increment column, you don't know which value MySQL created. You must fetch it and you can do it directly when you create the new user adding a parameter to the prepared statement:
PreparedStatement pstmt = conn.prepareStatement(sqlForNewUser, Statement.RETURN_GENERATED_KEYS);
pstmt.executeUpdate();
ResultSet keys = pstmt.getGeneratedKeys();
keys.next();
custId = keys.getInt(1);
Now you have the new user Id and can use it to insert the other values:
String sql = "INSERT INTO forgotpassword (PwdId,SecretQuestion1,SecretAnswer1,SecretQuestion2,SecretAnswer2,CustId,LoginId)VALUES(?,?,?,?,?,(SELECT CustId FROM signup WHERE CustId = ?),(SELECT LoginId FROM login WHERE CustId = ?))";
//...
ps.setString(6, custId);
ps.setString(7, custId);

About a MySql statement in Java Eclipse

I use MySql database and I use eclipse Java and JDBC to connect. I have a question about SQL statement. I have a table and 4 columns which are id_desk, id_time, user_name and user_passwords. I want to get all informations (all columns information) by using user_name. HOw can i get one row's all informations?
Connection dbConnection = null;
PreparedStatement preparedStatement = null;
//Put your table name instead of TABLE
String query = "SELECT id_desk, id_time, user_name, user_passwords FROM TABLE WHERE user_name = ?";
try {
//Provide your Database credentials
dbConnection = DriverManager.getConnection(DB_CONNECTION, DB_USER,DB_PASSWORD);
preparedStatement = dbConnection.prepareStatement(query);
//Replace somename with whatever username you querying
preparedStatement.setString(1,"somename");
// execute select SQL stetement
ResultSet rs = preparedStatement.executeQuery();
while (rs.next()) {
//Here you will get the result of the query, ONE row at a time.
}
} catch (SQLException e) {
System.out.println(e.getMessage());
} finally {
//Cleanup code
if (preparedStatement != null) {
preparedStatement.close();
}
if (dbConnection != null) {
dbConnection.close();
}
}
The query you would want to use will be similar to:
Select id_desk, id_time, user_name, user_passwords FROM table
WHERE user_name = (whatever your username is)
Storing pure user passwords in a database is not very secure, and you will almost always want to encode them in some way (there are countless resources online with examples of how to do this and why, google them).

check if the record exists in database

I need to check the box no if exist in the database under the remittance id that I enter if the box no exists then i need to show the message that the box no already exists but if it doesn't the it should insert new box i have written some code but its showing error
private void txtboxnoFocusLost(java.awt.event.FocusEvent evt) {
DBUtil util = new DBUtil();
try {
Connection con = util.getConnection();
PreparedStatement stmt = con.prepareStatement(
"select box_no from dbo.soil_det where rm_id = ? and box_no = ?");
stmt.setLong(1, Long.parseLong(tf_rm_id.getText()));
stmt.setString(1, (txtboxno.getText()));
ResultSet rs=stmt.executeQuery();
while(rs.next()){
rs.equals().txtboxno.getText());
}
JOptionPane.showMessageDialog(rootPane, "hello!S");
} catch (Exception ex) {
Logger.getLogger(DATAENTRY.class.getName()).log(Level.SEVERE, null, ex);
}
Try this code
private void txtboxnoFocusLost(java.awt.event.FocusEvent evt) {
DBUtil util = new DBUtil();
try {
Connection con = util.getConnection();
PreparedStatement stmt = con.prepareStatement(
"select box_no from dbo.soil_det where rm_id = ? and box_no = ?");
stmt.setLong(1, Long.parseLong(tf_rm_id.getText()));
stmt.setString(2, (txtboxno.getText()));
ResultSet rs=stmt.executeQuery();
bool recordAdded = false;
while(!rs.next()){
/// Do your insertion of new records
recordAdded = true;
}
if( recordAdded ){
JOptionPane.showMessageDialog(rootPane, "Record added");
}else{
JOptionPane.showMessageDialog(rootPane, "Record already exists");
}
} catch (Exception ex) {
Logger.getLogger(DATAENTRY.class.getName()).log(Level.SEVERE, null, ex);
}
or you could use a count:
String query = "select count(*)
from dbo.soil_det where rm_id = ? and box_no = ?";
then after executing the query you get the count with
rs.getInt(1)
using that you can decide which info to show to the user
very First You have to get count using sql if count is greater than zero then do not insert records and show message like already exists and in else part insert record. see following example
private boolean findCount(int rm_id,String box_no)
{
int count=0;
//write query here
count = assign query result;
//check count
if(count>0)
{
return false;//records exists
}else{
return true;//records do not exists
}
}
public void insertData()
{
if(findCount(1,"1")){//pass values
//Write down your insert logic
}else{
JOptionPane.showMessageDialog(rootPane, "Records Already Exists");
}
}
Note: Friend in Your Example you have not written the insert logic. only select was there
First you could add -- on the db table -- a unique constrain on the columns (rm_id, box_no), this is anyway a good thing to do.
Then you could simply try to insert the box and catch the exception and check if it is a violation of the unique constraint.
Another option (still keeping the unique constraint) would be to make a more complicated SQL insert statement that inserts only if not existing, you may google "sql insert if not exist" to find some examples...
You need to get the appropriate record from the ResultSet e.g.
boolean found = rs.getString(1).equals().txtboxno.getText());
At the moment you're simply comparing the ResultSet object itself to a string, and that won't work. The above pulls the first record from the ResultSet and performs the comparison on that (note: your datatype may be different and you may need rs.getInt(1) etc.)
Perhaps its sufficient in your case just to check if you have a ResultSet result (via rs.next())
simplified version
private void txtboxnoFocusLost(java.awt.event.FocusEvent evt) {
DBUtil util = new DBUtil();
try {
Connection con = util.getConnection();
PreparedStatement stmt = con.prepareStatement(
"select box_no from dbo.soil_det where rm_id = ? and box_no = ?");
stmt.setLong(1, Long.parseLong(tf_rm_id.getText()));
stmt.setString(2, (txtboxno.getText()));
ResultSet rs=stmt.executeQuery();
if(!rs.next()){
JOptionPane.showMessageDialog(rootPane, "Record added");
}else{
JOptionPane.showMessageDialog(rootPane, "Record already exists");
}
} catch (Exception ex) {
Logger.getLogger(DATAENTRY.class.getName()).log(Level.SEVERE, null, ex);
}
rs.next() followed by if condition returns true if the record exists in a table. if not, return false.

Categories

Resources