Update sql statement in servlet not in servlet - java

I am trying to allow the user to change the password if he enters the right username. The username is drawn from the database and compared to the username the user enter in a form. My problem is after the validation is done the UPDATE statement is not producing any result. Can someone help me out please?
String un = request.getParameter("username");
String psw = request.getParameter("password");
String cPsw = request.getParameter("cpassword");
Connection con = ConnectionHelper.getConnection();
try {
ResultSet rs = userList(con);
if (rs.next()) {
String n = rs.getString("username");
if (n.equals(un)) {
out.print("Password match");
String updateQuery = "UPDATE RegisteredUserInfo SET password ='"
+ cPsw + "'WHERE username ='" + un + "'";
PreparedStatement ps1 = con.prepareStatement(updateQuery);
ps1.executeQuery();
ServletContext context = getServletContext();
RequestDispatcher rd = context
.getRequestDispatcher("/Welcome.jsp");
rd.forward(request, response);
}
}
} catch (SQLException sx) {
out.println();
}
}
public ResultSet userList(Connection con) throws SQLException {
PreparedStatement ps;
ResultSet rs;
String matchingUname = "SELECT username FROM RegisteredUserInfo";
ps = con.prepareStatement(matchingUname);
rs = ps.executeQuery();
return rs;`

Try with ps1.execute(); or ps1.executeUpdate() instead of ps1.executeQuery();
Call con.commit(); to commit the changes and Don't forget to close the resources in the end.
Check the return type of below methods to make sure that data is inserted properly.
ResultSet executeQuery()
Executes the SQL query in this PreparedStatement object and returns the ResultSet object generated by the query.
int executeUpdate()
Executes the SQL statement in this PreparedStatement object, which must be an SQL INSERT, UPDATE or DELETE statement; or an SQL statement that returns nothing, such as a DDL statement.
Ream more about Difference between execute, executeQuery, executeUpdate
Points to Remember
Use PreparedStatement instead of using single quoted query string that may cause issue. Find a sample on Using Prepared Statements
Don't forget to close the resources such as connection, result set and statement.
Use finally block to handle it or Read more about Java7 -The try-with-resources Statement
Don't simply eat the exception in catch block. Do proper handling of the exception. You can try with e.printStackTrace() while development.

You need to call executeUpdate() for SQL UPDATE (or INSERT/DELETE).
String updateQuery = "UPDATE RegisteredUserInfo SET password = ?"
+ " WHERE username = ?";
PreparedStatement ps1 = con.prepareStatement(updateQuery);
ps1.setString(1, cPsw);
ps1.setString(2, un);
ps1.executeUpdate();
Also use the PreparedStatement as above. Look for SQL Injection, also escapes '.

Related

How can I only get 1 element from a SQL Database?

I have a small problem. I wrote a method in which I have an SQL query that should output a correct string after 2 parameters. When debugging, however, the result is not the right element. I don't know why this happens.
public static String findRightTemplate(String user_name, int template_id)
throws Exception {
Connection conn = DriverManager.getConnection(
"xxx", "xxx", "xxx");
Statement st = conn.createStatement();
st = conn.createStatement();
ResultSet rs = st.executeQuery(
"SELECT template FROM templates " +
"where template_id=template_id AND user_name=user_name"
);
String temp="";
while(rs.next())
{
temp=rs.getString("template");
}
rs.close();
st.close();
conn.close();
I ask for the username and template_id and I just want to get an element out of the template column.
The SQL query is correct. I've already tested that. But it seems that the query runs through all elements with the same username. As a result, I only get the last element and not the right one.
UPDATE
Currently you do not use the method parameters inside your query. As already suggested you should use a PreparedStatement to fix that. You should basically do the following:
public static String findRightTemplate(String userName, int templateId) throws SQLException {
try (final Connection connection = DriverManager.getConnection("...")) {
final PreparedStatement preparedStatement = connection.prepareStatement(
"SELECT template " +
"FROM templates " +
"WHERE user_name = ? " +
"AND template_id = ? " +
"LIMIT 1"
);
preparedStatement.setString(1, userName);
preparedStatement.setInt(2, templateId);
final ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()) {
return resultSet.getString(1);
}
}
return null;
}
If you do not use a PreparedStatement and build the query manually as suggested in the comments your application could be vulnerable to SQL injection attacks.

Delete function using jsp and servlet

Hi can someone help me to figure out where is my silly mistake.
i am trying to find out in internet but couldnot find the best solution. i have a jsp and java controller where i should be able to delete a record from the databas, following is my code. any help will be acknowledge
public void doDel(HttpServletRequest request, HttpServletResponse response) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
try {
HttpSession session = request.getSession(true);
messageBean mbean = new messageBean();
int id = mbean.getMesId();
String sql;
sql = "DELETE * from message where id =?";
Class.forName(driver).newInstance();
conn = DriverManager.getConnection(url);
st = conn.createStatement();
ps = conn.prepareStatement(sql);
ps.setInt(1, id);
ps.executeUpdate();
conn.commit();
conn.close();
There should be no * after delete, it's just delete from.
Change your query as
sql = "DELETE from message where id =?";
Or otherwise use statement query as
sql = "DELETE from message where id ="+id;
Statement st = conn.createStatement();
stmt.executeQuery(sql);
Reference for delete query using Statement
There are few things to note:
st = conn.createStatement(); is not needed. Because you are already using PreparedStatement.
sql = "DELETE * from message where id =?"; This can be written as:
sql = "DELETE from message where id =?"; //No need of *
conn.commit(); is needed only if you are setting conn.setAutoCommit(false);
You must provide Error/Stacktrace to get useful answers.

SQL command from eclipse using JDBC

I have been searching and trying different stuff for awhile, but have not found an answer. I'm trying to make a connection to sql using JDBC from eclipse. I am having trouble when I need to select a string in the database. If I use:
Select name from data where title = 'mr';
That works with terminal/command line but when I try to use eclipse where I use
statement sp = connection.createstatement();
resultset rs = sp.executequery("select name from data where title = '" + "mr" + "'");
It does not give me anything while the terminal input does. What did I do wrong in the eclipse? Thanks
Heres a part of the code. Sorry, its a bit messy, been trying different things.
private boolean loginChecker(String cid, String password) throws SQLException{
boolean check = false;
PreparedStatement pstatment = null;
Statement stmt = null;
//String query = "SELECT 'cat' FROM customer";
String query = "select '"+cid+"' from customer where password = '"+password+"'";
try {
System.out.println("in try......");
//stmt = con.createStatement();
//ResultSet rs = stmt.executeQuery(query);
PreparedStatement prepStmt = con.prepareStatement(query);
ResultSet rs = prepStmt.executeQuery();
//System.out.print(rs.getString("cid"));
while(rs.next()){
check = true;
System.out.print(rs.getString("cid"));
}
} catch (SQLException e ) {
e.printStackTrace();
} finally {
if (stmt != null) {
//stmt.close();
}
}
return check;
}
Second try on a simpler query:
public List<Object> showTable() {
List<Object> result = new ArrayList<Object>();
String name = "bob";
try
{
PreparedStatement preStatement = con.prepareStatement("select total from test where name = ?");
preStatement.setString(1, name);
ResultSet rs1 = preStatement.executeQuery();
while(rs1.next()){
System.out.println("there");
System.out.println(rs1.getInt("total"));
}
}
catch (SQLException ex)
{
System.out.print("Message: " + ex.getMessage());
}
return result;
}
Remove the quotes around the column name.
String query = "select "+cid+" from customer where password = '"+password+"'";
You've not mentioned which database you're working with but many databases like Oracle change the column case to upper case unless they're quoted. So, you only quote table columns if that's how you had created them. For example, if you had created a table like
CREATE TABLE some_table ( 'DoNotChangeToUpperCase' VARCHAR2 );
Then you would have to select the column with quotes as well
SELECT 'DoNotChangeToUpperCase' FROM some_table
But, if you didn't create the table using quotes you shouldn't be using them with your SELECTs either.
Make sure you are not closing the ResultSet before you are trying to use it. This can happen when you return a ResultSet and try to use it elsewhere. If you want to return the data like this, use CachedRowSet:
CachedRowSet crs = new CachedRowSetImpl();
crs.populate(ResultSet);
CachedRowSet is "special in that it can operate without being connected to its data source, that is, it is a disconnected RowSet object"
Edit: Saw you posted code so I thought I add some thoughts. If that is your ACTUAL code than the reason you are not getting anything is because the query is probably not returning anything.
String query = "select '"+cid+"' from customer where password = '"+password+"'";
This is wrong, for two reasons. 1) If you are using prepared statements you should replace all input with '?' so it should look like the following:
String query = "select name from customer where password = ?";
Then:
PreparedStatement prepStmt = con.prepareStatement(query);
prepStmt.setString(1, password);
ResultSet rs = prepStmt.executeQuery();
2)
System.out.print(rs.getString("cid"));
Here are are trying to get the column named "cid", when it should be the name stored in cid. You should actually never be letting the user decide what columns to get, this should be hardcoded in.

Passing parameters to a JDBC PreparedStatement

I'm trying to make my validation class for my program. I already establish the connection to the MySQL database and I already inserted rows into the table. The table consists of firstName, lastName and userID fields. Now I want to select a specific row on the database through my parameter of my constructor.
import java.sql.*;
import java.sql.PreparedStatement;
import java.sql.Connection;
public class Validation {
private PreparedStatement statement;
private Connection con;
private String x, y;
public Validation(String userID) {
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/test", "root", "");
statement = con.prepareStatement(
"SELECT * from employee WHERE userID = " + "''" + userID);
ResultSet rs = statement.executeQuery();
while (rs.next()) {
x = rs.getString(1);
System.out.print(x);
System.out.print(" ");
y = rs.getString(2);
System.out.println(y);
}
} catch (Exception ex) {
System.out.println(ex);
}
}
}
But it doesn't seem work.
You should use the setString() method to set the userID. This both ensures that the statement is formatted properly, and prevents SQL injection:
statement =con.prepareStatement("SELECT * from employee WHERE userID = ?");
statement.setString(1, userID);
There is a nice tutorial on how to use PreparedStatements properly in the Java Tutorials.
If you are using prepared statement, you should use it like this:
"SELECT * from employee WHERE userID = ?"
Then use:
statement.setString(1, userID);
? will be replaced in your query with the user ID passed into setString method.
Take a look here how to use PreparedStatement.
There is a problem in your query..
statement =con.prepareStatement("SELECT * from employee WHERE userID = "+"''"+userID);
ResultSet rs = statement.executeQuery();
You are using Prepare Statement.. So you need to set your parameter using statement.setInt() or statement.setString() depending upon what is the type of your userId
Replace it with: -
statement =con.prepareStatement("SELECT * from employee WHERE userID = :userId");
statement.setString(userId, userID);
ResultSet rs = statement.executeQuery();
Or, you can use ? in place of named value - :userId..
statement =con.prepareStatement("SELECT * from employee WHERE userID = ?");
statement.setString(1, userID);
Do something like this, which also prevents SQL injection attacks
statement = con.prepareStatement("SELECT * from employee WHERE userID = ?");
statement.setString(1, userID);
ResultSet rs = statement.executeQuery();
You can use '?' to set custom parameters in string using PreparedStatments.
statement =con.prepareStatement("SELECT * from employee WHERE userID = ?");
statement.setString(1, userID);
ResultSet rs = statement.executeQuery();
If you directly pass userID in query as you are doing then it may get attacked by SQL INJECTION Attack.

Getting java.sql.SQLException: Operation not allowed after ResultSet closed

When I execute the following code, I get an exception. I think it is because I'm preparing in new statement with he same connection object. How should I rewrite this so that I can create a prepared statement AND get to use rs2? Do I have to create a new connection object even if the connection is to the same DB?
try
{
//Get some stuff
String name = "";
String sql = "SELECT `name` FROM `user` WHERE `id` = " + userId + " LIMIT 1;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
name = rs.getString("name");
}
String sql2 = "SELECT `id` FROM `profiles` WHERE `id` =" + profId + ";";
ResultSet rs2 = statement.executeQuery(sql2);
String updateSql = "INSERT INTO `blah`............";
PreparedStatement pst = (PreparedStatement)connection.prepareStatement(updateSql);
while(rs2.next())
{
int id = rs2.getInt("id");
int stuff = getStuff(id);
pst.setInt(1, stuff);
pst.addBatch();
}
pst.executeBatch();
}
catch (Exception e)
{
e.printStackTrace();
}
private int getStuff(int id)
{
try
{
String sql = "SELECT ......;";
ResultSet rs = statement.executeQuery(sql);
if(rs.next())
{
return rs.getInt("something");
}
return -1;
}//code continues
The problem is with the way you fetch data in getStuff(). Each time you visit getStuff() you obtain a fresh ResultSet but you don't close it.
This violates the expectation of the Statement class (see here - http://docs.oracle.com/javase/7/docs/api/java/sql/Statement.html):
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.
What makes things even worse is the rs from the calling code. It is also derived off-of the statement field but it is not closed.
Bottom line: you have several ResultSet pertaining to the same Statement object concurrently opened.
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.
I guess after while(rs2.next()) you are trying to access something from rs1. But it's already closed since you reexecuted statement to get rs2 from it. Since you didn't close it, I beleive it's used again below.

Categories