Parametrized queries in java - java

I am facing a problem with retrieving a column from database
This is my code
public String ShowtimeQur(int MovieID)
{
rs3 = null;
String RoomID=null;
String ShowTime = null;
try
{
String qu ="Select Room_ID from Movie_Shows_in where Movie_ID="+MovieID;
//getRoomQur.setInt(1, MovieID);
rs3=getRoomQur.executeQuery(qu);
RoomID=rs3.getString("Room_ID");
getShowtimequr.setString(1, RoomID);
rs4=getShowtimequr.executeQuery();
ShowTime=rs4.getString("Show_Times");
}
catch (SQLException e)
{
e.printStackTrace();
}
return ShowTime;
}
I keep get this type of error
java.sql.SQLException: Invalid operation at current cursor position.

Use PreparedStatement.
PreparedStatement statement = con.prepareStatement("Select Room_ID from Movie_Shows_in where Movie_ID=?");
statement.setInt(1, MovieID);
ResultSet res = statement.executeQuery()
...
rest of your code
Never, never, never use string concatenation to build queries, as you put yourself at risk of SQL Injection

Like the answer before, you shoud declare a "ResulSet result" variable, and after the execute of the query, you should call "result.next()" method to point the cursor on the first row (initially is pointed to row 0 which does not exist) and then call a retrive data mehod like "result.getString(columnNumber)" by example.

Related

How do I turn my INT (id) into a String in my return from MySQL?

I'm trying to my a very simple webapplication, webshop, for cupcakes.
From the webApp you can choose a cupcake form the dropdown with three attributes
(top, bottom, quantity). These are stored in an ArrayList on my sessionScope but all in numbers e.g. Chokolate as 1 and Vanilla as 2. I want to use these topId numbers to ask my DB (MySQL) for what is in 1 and then have it return Chokolate.
I think I am almost there with my code, but can't get it to return my String, as my topId is an Int.
public static Top getTopById(int topId) {
readFromArrayPutInSQL();
String sql = "INSERT INTO cupcaketopping (toppingType, toppingPrice) VALUES (?, ?)";
try {
ConnectionPool connectionPool = new ConnectionPool();
String query = "SELECT toppingType FROM cupcaketopping";
Statement statement = connectionPool.getConnection().createStatement();
ResultSet rs = statement.executeQuery(query);
rs.getString(topId);
} catch (SQLException e) {
throw new RuntimeException(e);
}
return topId; //Here is the problem - I GUESS?
}
Code after changes due to input in comments, seem to be working!
public static Top getTopById(int topId) {
readFromArrayPutInSQL();
String query = "SELECT toppingType FROM cupcaketopping WHERE toppingID = "+topId+"";
try {
ConnectionPool connectionPool = new ConnectionPool();
PreparedStatement preparedStatement = connectionPool.getConnection().prepareStatement(query);
ResultSet rs = preparedStatement.executeQuery(query);
rs.next();
return new Top(rs.getString(1));
//connectionPool.close(); //NOTE! Won't run, IntelliJ is asking me to delete!
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
There are a few problems:
You're selecting all rows from the cupcaketopping table, regardless of the topId. You should probably be using a PreparedStatement, and then use topId as part of your query.
You never call ResultSet#next(). The result set always starts "before" the first row. You have to call next() for each row in the result set (it returns true if there is a row to read).
The ResultSet#getString(int) method gets the String value of the column at the given index of the result. You only select one column, so the argument should probably be 1 (not topId).
You never close the Statement when done with it.
Depending on how your connection pool class works, you might actually need to close the Connection instead.
You never try to use the String returned by rs.getString(topId).
You never try to convert the query result to a Top instance.
Given it's possible the query will return no result, you might want to consider making the return type Optional<Top>.
The sql string seems to have no purpose.
Your code should look more like this:
public Optional<Top> getTopById(int topId) {
Connection conn = ...;
String query = "SELECT toppingType FROM cupcaketopping WHERE id = ?";
// closes the statement via try-with-resources
try (PreparedStatement stat = conn.prepareStatement(query)) {
stat.setInt(1, topId);
ResultSet rs = stat.executeQuery();
// assume unique result (as it's assumed the ID is the primary key)
if (rs.next()) {
// assumes 'Top' has a constructor that takes a 'String'
return Optional.of(new Top(rs.getString(1)));
} else {
return Optional.empty();
}
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
}
Your actual implementation may vary, depending on how the rest of your code is designed.

Select * From java with preparedStatement [duplicate]

This question already has answers here:
Java MYSQL Prepared Statement Error: Check syntax to use near '?' at line 1
(2 answers)
Closed 1 year ago.
I faced this problem today with my select SQL. This method is supposed to show data from database in tex tfields. I changed it from statement to preparedStatement, but I faced a problem.
public Entreprise loadDataModify(String id) {
Entreprise e = new Entreprise();
PreparedStatement stmt;
try {
String sql = "SELECT * FROM user WHERE mail=?";
stmt = cnx.prepareStatement(sql);
stmt.setString(1, id);
ResultSet rst = stmt.executeQuery(sql);
while (rst.next()) {
stmt.setString(2, e.getNom());
stmt.setString(3, e.getEmail());
stmt.setString(4, e.getTel());
stmt.setString(5, e.getOffre());
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
return e;
}
It shows i have problem with syntax and the output is " nu
You're calling the wrong method. Unlike Statement, when you're using a PreperedStatement you should first set the values for the parameters, and after you can call on that instance executeQuery() method.
Also, it's a best practice to use try-with-resources, because a Statement or PreparedStament object is a Resource (a resource is a class that implements AutoCloseable interface) and you have to close it. Using try-with-resources, it's done automatically.
The ResultSet instance is also a resource, but it's closed when the statement object is closed, so you don't have to close it explicitly.
So, the best way to solve your problem will be:
String selectAllByMail = "SELECT * FROM user WHERE mail=?";
try (PreparedStatement prpStatement = connection.prepareStatement(selectAllByMail)) {
// use prpStatement
prpStatement.setString(1, id);
ResultSet resultSet = prpStatement.executeQuery();
while (resultSet.next()) {
// process resultSet
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}
You are not filling your Enterprise object. And you are not using executeQuery() function correctly. As seen below, the parameter inside the brackets has been removed. PreparedStatements first of all need the values of the parameters (your ? in the query) and then the formed query has to be executed. If you give a String parameter to executeQuery() then the query in the brackets will be executed.
And the part where Enterprise is being filled could be seen below.
This would be the correct way:
public Entreprise loadDataModify(String id) {
Entreprise e = new Entreprise();
PreparedStatement stmt;
try {
String sql = "SELECT * FROM user WHERE mail=?";
stmt = cnx.prepareStatement(sql);
stmt.setString(1, id);
ResultSet rst = stmt.executeQuery();
while (rst.next())
{
// rst keeps the data, so you have to traverse it and get the data from it in this way.
e.setNom( rst.getString("HERE EITHER THE COLUMN NAME OR INDEX"));
e.setEmail( rst.getString("HERE EITHER THE COLUMN NAME OR INDEX"));
e.setTel( rst.getString("HERE EITHER THE COLUMN NAME OR INDEX"));
e.setOffre( rst.getString("HERE EITHER THE COLUMN NAME OR INDEX"));
}
} catch (SQLException ex) {
System.out.println(ex.getMessage());
}
return e;
}
Your call to executeQuery() should not be passing the query string. Use this version:
String sql = "SELECT * FROM user WHERE mail=?";
stmt = cnx.prepareStatement(sql);
stmt.setString(1, id);
ResultSet rst = stmt.executeQuery();
while (rst.next()) {
// process result set
}
Your current code is actually calling some overloaded Statement#executeQuery() method, which is not the version of the method which you want to be calling.

java - How to get max ID in SQL

It Takes Too Long For Me To Create And Send PreparedStatement's or ResultSet.
How Can I Get MaxID From SQL in Java Method?
Writed this but not working...
private static int getLastId()
{
int returned=0;
try
{
PreparedStatement stat;
ResultSet rs;
String sql="select max(id) from home";
stat=conn.prepareStatement(sql);
rs=stat.executeQuery();
while(rs.next())
{
returned = rs.getInt("id")+1;// just want a new id for new person
}
}
catch (Exception e)
{
System.out.println(""+e);
}
return returned;
}
I Tried To Use It Like This...
//reseting every thing and get lastId+1;
System.out.println("added");
field_name.setText("");
field_pass.setText("");
int temp= getLastId();
field_id.setText(""+temp);
But It Returns 0!
I Don't Have any SQL error.
Did I Use It Wrong?
or ?
Thanks For Help.
You have a few problems here, one of which is that in your current code you aren't actually accessing the max(id) which you put in the query. One way around this is to assign an alias:
PreparedStatement stat;
ResultSet rs;
String sql = "SELECT MAX(id) AS max_id FROM home";
stat = conn.prepareStatement(sql);
rs = stat.executeQuery();
if (rs.next()) {
returned = rs.getInt("max_id") + 1;
}
This fixes the syntax problem, but there is still the problem of whether this is the best way to get the next id. I would recommend that you switch to using an auto increment column, which MySQL will manage for you. Then, you don't need to worry about keeping track of the latest ID value. In fact, you don't even need to specify a value when inserting; the database will handle this for you.

Parameter not set error in Prepared statement

I'm trying to execute a prepared statement in JDBC, and everytime I execute it I get the error message "Paramater not set".
I have tried repeatedly to check for unset parameters - but I only have the one. This leads me to believe it is another foolish error on my part.
If you could point this out to me, I would be very grateful
public book search(String key){
book temp = null;
try {
String stmt = "SELECT BookID, Title, Author, Media, Available FROM BOOK WHERE Title LIKE ?;";
connection = DatabaseConnection();
PreparedStatement preparedStmt = connection.prepareStatement(stmt);
System.out.println(key);
preparedStmt.setObject(1, key);//the name
statement = connection.prepareStatement(stmt); //Using Prepared Statements prepare the query
resultSet = statement.executeQuery(); //Execute the query
while (resultSet.next()) {
int bookID = resultSet.getInt("BookID");//Get the userName
String title = resultSet.getString("Title"); //Get the score
String author = resultSet.getString("Author"); //Get the score
String media = resultSet.getString("Media"); //Get the score
boolean available = resultSet.getBoolean("Available"); //Get the score
temp = new book(title,author,media,available,bookID);
}
connection.close(); //close connection
} catch (SQLException e) {
System.err.println("Got an exception!");
System.err.println(e.getMessage());
}
return temp;
}
You're calling prepareStatement twice, setting the parameter on the first one but then calling executeQuery on the second.
It's not clear where you're event declaring statement or resultSet, but you want:
PreparedStatement preparedStmt = connection.prepareStatement(stmt);
preparedStmt.setString(1, key);
ResultSet resultSet = preparedStmt.executeQuery();
Note that I've made resultSet a local variable - you really don't want it to be a field... there's also no reason for your temp variable as you can just return directly from the while loop. (I've changed the code to use setString instead of setObject, too...)
You should use try-with-resources statements to close both the statement and the result set automatically...)

Unable to get value from ResultSet

I am working on a web application using Java and MySQL.
I created a method that is supposed to return an ArrayList of the respective column name based on the various tables in the database.
However, when I debugged the method, I realised the while(rs.next()) causes an error. I used this site for reference, hence I am not sure what went wrong.
This is the code. Thanks.
// Returns the the all the columns in the table
public ArrayList getColumnName(String tableName) throws SQLException {
ResultSet rs = null;
List<String> columnName = new ArrayList<String>();
Statement st = null;
Connection con = null;
try {
// Get a connection from the connection factory
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/information_schema", "root", "xxxx");
// Create a Statement object so we can submit SQL statements to the driver
st = con.createStatement();
StringBuilder sql = new StringBuilder("SELECT column_name FROM information_schema.columns " +
"WHERE table_schema = 'testDB' AND table_name = '");
sql.append(tableName).append("'");
rs = st.executeQuery(sql.toString());
while (rs.next()) { // getting error..
columnName.add(rs.getString("column_name"));
}
} catch (SQLException ex) {
Logger.getLogger(ModificationPage.class.getName()).log(Level.SEVERE, null, ex);
} finally {
if (con != null || st != null) {
st.close();
con.close();
}
}
return (ArrayList) columnName;
}
According to the Javadoc of 1.6 (not sure which version of Java you're using):
Throws:
SQLException - if a database access error occurs or this method is called on a closed result set
It's very, very unlikely that if you actually got to the line where rs.next() was called, that a database error occurred just then. So, the most likely result is that the result set was closed.
Please alter your code to the following and see if you still get the error on the same line:
while (!rs.isClosed() && rs.next()) { // getting error..
columnName.add(rs.getString("column_name"));
}
Also, Holy SQL Injection Attack, Batman!
Taking the raw string as you're doing and enclosing it within single quotes leads this code to have an SQL injection vulnerability. Basically all a malicious user has to do is end your query with a single quote (') and run a query of their own afterwards.
So, the exception never happens ?
A query error should be thrown at rs = st.executeQuery(sql.toString()) if that were the case, but if it make it to whileand didn't iterate, it's because of an empty resultset
Maybe you're passing wrong arguments to the query ?

Categories