Prepared Statement Error - java

Recently just changed my statements in SQL to prepared statements for security reasons and here's what I came up with..
Unfortunately it's coming up with an cannot find error on the
"SELECT * FROM owner WHERE username = ? AND" + "password = ?;";
The whole error:
Cannot find symbol:
symbol: method prepareStatement(java.lang.String)
location: variable dbAccess of type HolidayExchange.DBAccess
I realise that it's finding a String when it should be a preparedstatement but this is how I always see it in examples etc.
I'm probably doing something idiotic but any help solving this would be really helpful!
The whole method:
DBAccess dbAccess = new DBAccess();
String sql = "SELECT * FROM owner WHERE username = '?' AND"+
" password = '?'";
PreparedStatement ps = dbAccess.prepareStatement(sql);
ps.setString(1,u);
ps.setString(2,p);
ResultSet rs = dbAccess.executeQuery2(ps);
User user = new User();
while (rs.next()){
user.setFirstname(rs.getString("firstname"));
user.setSurname(rs.getString("surname"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
}
rs.close();
dbAccess.close();
if(user.getUsername().length()==0){
return null;
}else{
return user;
}
} catch (Exception e) {
return null;
}
}`

There is a space missing
// becomes ANDpassword in the resulting string:
"SELECT * FROM owner WHERE username = ? AND" + "password = ?;";
should be
// space added before passsword:
"SELECT * FROM owner WHERE username = ? AND" + " password = ?;";

Always log ps.toString() before you exeute a query. This will let programmer know what query actually is been executed.
Also, PreparedStatement are not strings
Connection con = null;
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql:localhost:3306/jdbctutorial","root","root");
PrepareStatement ps = con.prepareStatement(sqlQuery);

Cannot find symbol: symbol: method prepareStatement(java.lang.String)
location: variable dbAccess of type HolidayExchange.DBAccess
This error message does not have anything to dot with ill-formatted SQL. It is a compile time error. HolidayExchange.DBAccess class does not have method named prepareStatement that takes java.lang.String as argument.
Your SQL is not validated (or evaluated) in compile time, so it cannot be reason for compile time errors. Once you get it to compile, you probably will find that after you remove single quotes that are around question marks, your query will work fine.

if you have the import com.mysq.jdbc.*; remove it and change it to
import java.sql.PreparedStatement; hence vice versa, coz I think that it's either the PreparedStatement method that you are using is not suitable for the database you are connecting.

For each question mark try putting single quotes around them.
'?'

Related

Value of ResultSet when the SQL statement is a wrong syntax?

I am using mySQL. As you see, the SQL statement is wrong at SELECT. So, I wonder what value the rs is?
I hope to get some advice. I thank you so much;
String sql = "SELCT * FROM user WHERE username = '" + username + "' and password = '" + password + "'";
ResultSet rs = stm.executeQuery(sql);
There would be no value because Statement.executeQuery(String) would throw a SQLException. As the linked Javadoc says,
Returns:
a ResultSet object that contains the data produced by the given query; never null
Throws:
SQLException - if a database access error occurs, this method is called on a closed Statement, the given SQL statement produces anything other than a single ResultSet object, the method is called on a PreparedStatement or CallableStatement
It will return you an exception having message like syntax error.
Easiest way to find is to debug your code by putting break points in code & examining / watching values of variables . Most IDEs have these debugging features. In addition to Elliott Frisch's answer, if I restructure your code like below then in case of invalid / incorrect SQL, control comes to catch block and you can see that value of rs remains null.
public void executeQuery(Connection conn, String username,String password) {
String sql = "SELCT * FROM user WHERE username = '" + username + "' and password = '" + password + "'";
ResultSet rs = null;
Statement stm = null;
try {
stm = conn.createStatement();
rs= stm.executeQuery(sql);
while(rs.next()) {
//Extract ResultSet here as per needed logic
}
} catch (SQLException e) {
// Your control comes here if query is wrong , put a break point at below line & examine value of rs
e.printStackTrace();
}finally {
// Close resources not needed after this method call like - result sets , statements & connection
}
}
Firstly statement won't execute, so next execution is depends on how you are going to handle that exception. So, if exception comes and if you handle also there will be null in ResultSet because no value assigned to it.

SQL Command to search from Java program

I am attempting to allow keyboard input from my Java Project to search for a Car License number (VARCHAR), from my database. I am getting an error in my tester class about SQL syntax error. What would be the correct procedure so that when I search for a license it will display that license. Thanks in advance
public Car getCar(String searchLicense) {
Car foundCar = new Car();
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url + dbName, userName, password);
statement = conn.createStatement();
resultSet = statement.executeQuery(
"select * from eflow.registration.cLicense where="+searchLicense);
while (resultSet.next()) {
foundCar = new Car(resultSet.getInt("cID"), resultSet.getString("cLicense"),
resultSet.getInt("cJourneys"), resultSet.getString("cUsername"),
resultSet.getString("cPassword").toString());
}
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
return foundCar;
}
You missing single quote and column name also..
resultSet = statement.executeQuery(
"select * from eflow.registration.cLicense where cLicenseName='"+searchLicense+"'");
Better solution,try this..
resultSet = statement.executeQuery(
"select * from eflow.registration.cLicense where cLicenseName like '%"+searchLicense+"%'");
The direct problem you're talking about it that you are missing quotation on your query, since it is a string. so what #Dakoda suggested in the comments should solve it.
however, the bigger issue here is that you are vulnerable to SQL injection, as you are allowing user input into your query. If I'll put input like xxx' or 'a' ='a I'll be able to fetch your entire database.
You should use parameterized query to protect yourself

Parameter index out of range (1 > number of parameters, which is 0)

I get this error, Can anyone help me in finding my mistake in the query?
public boolean populateLeagues(String leaguename, String password){
Connect connect = new Connect();
Connection conn = connect.Connection();
Statement stmt = conn.createStatement();
String query = "INSERT INTO users VALUES('" + leaguename + "')";
stmt.executeUpdate(query);
conn.close();
}
AS #Jon Skeet says, use a prepared statement and inject parameters into. In this way you don't have to figure out all hassles about sql injection and data format(think about using a query like the one you provide to store datetime globally).
Probably leaguename value is null. Remember that default value for string type isn't the empty strin but null
You use single quote around leaguename, since we don't know how leaguename is formatted, that might lead to errors

Soap query database

I write a opration on java soap service to query the database and then show the data I have searched on client jsp page. However, I can't show it, the variable "rs" cannot change, I don't know why? could someone help me to find the troboule?
This is the opration i create on soap service:
#WebMethod(operationName = "query")
public String query(#WebParam(name = "parameter") String parameter) {
ResultSet rs;
try {
Connection con = data1.getConnection();
Statement statement = con.createStatement();
String QueryString;
QueryString = "SELECT * from stud where name= parameter";
rs = statement.executeQuery(QueryString);
while (rs.next()) {
System.out.println(rs.getInt(1) + " " + rs.getString(2) + "\n");
}
} catch (Exception ex) {
System.out.println("Unable to connect to batabase.");//TODO write your implementation code here:
}
//TODO write your implementation code here:
return null;
}
I'm not totally sure I understand your question. Maybe you mean that you can view the console output and this process that rs is an empty result set. You said rs cannot change, but you probable realize that rs stores the entire result set and you only assign it once, so it doesn't "change" if your code is working currently.
One obvious thing that is wrong is that parameter is a variable (in fact, a parameter!) But you include it inside the quotes as part of the query string. So regardless if the function input, you are searching the database for the name "parameter"

Oracle Java SQL Exception Error: ORA-0094

I am trying to write a function for this button. I want to be able to pass it a textfield value and be able to go into my database to retrieve some information.....
Can somebody explain to me what is going on and provide me a solution to this madness?
Thank you all xD
I keep running into this stupid problem:
ACTION1 createdoracle.jdbc.driver.T4CConnection#484845aa
Exception:java.sql.SQLSyntaxErrorException: ORA-00904: "ART": invalid identifier
Code:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
//CLASS TYPE
//LIST ALL OFFERED CLASSES AND REVENUE
try{
String classtype = jTextField1.getText().trim();
if(classtype.equals("")){
JOptionPane.showMessageDialog(this, "Sorry Wrong input.... Please try again....");
}
else if(classtype != ""){
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn=DriverManager.getConnection(
"jdbc:oracle:thin:#fourier.cs.iit.edu:1521:orcl",
"usr","pwd");
Statement stmt = conn.createStatement();
System.out.println("ACTION1 created"+conn+"\n\n");
String ct = jTextField1.getText().trim();
//String aa = "SELECT * FROM CLASS WHERE TYPE="+classtype;
//System.out.println(aa);
ResultSet rset = stmt.executeQuery("SELECT * FROM CLASS WHERE TYPE="+ct);
while (rset.next()) {
System.out.println(rset.getString("TITLE") + " ");
}
JOptionPane.showMessageDialog(this, "Class Type: "+classtype);
stmt.close();
conn.close();
System.out.println("Connection Closed");
}
catch(Exception sqle){
System.out.println("\nException:"+sqle);
}
}
}
catch(Exception e){
JOptionPane.showMessageDialog(this, "Please Retry input....", "Error", JOptionPane.ERROR_MESSAGE);
}
}
Let me guess ... does the ct String start with "ART" (or some variation)?
If so, the problem is that SQL requires quotes around string literals. Your query probably looks to Oracle something like this:
SELECT * FROM CLASS WHERE TYPE=Art of War
but it should look like
SELECT * FROM CLASS WHERE TYPE='Art of War'
There are two ways to fix this:
Assemble the query with quote characters around ct.
Write the query as "SELECT * FROM CLASS WHERE TYPE=?", use a PreparedStatement instead of a Statement and use the setString method to supply the parameter value.
If done properly, the second approach is both more secure and more efficient. (The problem with string-bashing the query and using Statement is that you are potentially making yourself vulnerable to SQL injection attacks.)
You're passing the value as part of the query, and the string concatenation you're doing makes the SQL into:
SELECT * FROM CLASS WHERE TYPE=ART
(where ART is the value of ct from the textfield) so it's trying to find a column on the table called ART. At an absolute minimum you need to quote the string:
ResultSet rset = stmt.executeQuery("SELECT * FROM CLASS WHERE TYPE='" + ct + "'");
But really don't do this; as #Andreas_D says you're leaving yourself open to SQL injection. Always use prepared statements and bind variables:
String sql = "SELECT * FROM CLASS WHERE TYPE=?";
PrepareStatement stmt = conn.prepareStatement(sql);
stmt.setString(1, ct);
ResultSet rset = stmt.executeQuery();

Categories

Resources