SELECT with WHERE using PreparedStatement - java

I have this method that selects movie showtimes by movie ID from a MySQL database and puts them in a Time[]. However, it is throwing a syntax exception near '? ORDER BY schedule_id' according to the trace.
public Time[] getShowTimes(int movieId) {
List<Time> list = new ArrayList<Time>();
try {
sql = "SELECT schedule_time FROM schedule WHERE movie_id = ? ORDER BY schedule_id";
ps = conn.prepareStatement(sql);
ps.setInt(1, movieId);
rs = ps.executeQuery(sql);
while(rs.next()) {
list.add(rs.getTime(1));
}
} catch(SQLException se) {
se.printStackTrace();
}
Time[] times = new Time[list.size()];
times = list.toArray(times);
return times;
}
I followed this example (if that helps). What could be wrong?

You are calling the executeQuery(String) method in your PreparedStatement, and that call is just inherited from Statement. But Statement just executes the query without any PreparedStatement placeholder semantics, hence the error.
Instead, you want to call the executeQuery() (no arguments) method. The SQL has already been prepared, and all placeholders have been assigned values, so the SQL argument string is not needed again.
rs = ps.executeQuery();

Related

java.sql.SQLException: Operation not allowed after ResultSet closed [help] [duplicate]

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.

Executing multiple queries with single PS

i have created prepared statement object .
now i want to get the result of multiple queries . is it possible to do using single prepared statement object/ find the piece code below
PreparedStatement ps = null;
String moviedirectorQry = "SELECT movie_director FROM movies WHERE movie_title= ?";
ps = dbConnection.prepareStatement(moviedirectorQry);
ps.setString(1, "Twilight");
ResultSet rs=null;
rs = ps.executeQuery(moviedirectorQry);
while (rs.next()) {
String director_name = rs.getString("movie_director");
System.out.println("director name : " + director_name);
}
now i want to run another query.. how to do
If the idea is to use the same PreparedStatement for different queries of the same type with only parameters' value that change, yes it is possible, simply call clearParameters() first to clear the parameters in case you want to reuse it before setting the new parameters' value.
The code could be something like that:
if (ps == null) {
// The PreparedStatement has not yet been initialized so we create it
String moviedirectorQry = "SELECT movie_director FROM movies WHERE movie_title= ?";
ps = dbConnection.prepareStatement(moviedirectorQry);
} else {
// The PreparedStatement has already been initialized so we clear the parameters' value
ps.clearParameters();
}
ps.setString(1, someValue);
ResultSet rs = ps.executeQuery();
NB: You are supposed to use executeQuery() not ps.executeQuery(moviedirectorQry) otherwise the provided parameters' value will be ignored such that the query will fail.

Why won't my query run properly? When ever I pass a string variable through the executeQuery method I get an error

There is an error on the line that says ps = stmt.executeQuery();....the error says method executeQuery in interface Statement cannot be applied to given types;
required: String
found: no arguments
reason: actual and formal argument lists differ in length
But whenever I pass a String through that line I get an error saying java.sql.SQLException:Method 'executeQuery(String)' not allowed on prepared statement...
This method is for a button that adds all the Integer values in a column of SQL table.
private void btnCalculateActionPerformed(java.awt.event.ActionEvent evt) {
try{
String SQL = "SELECT SUM(PRICE) FROM MENU";
stmt = con.prepareStatement(SQL);
ps = stmt.executeQuery();
if(ps.next()) {
String total = ps.getString("SUM(PRICE)");
textTotalCost.setText(total);
}
}
catch (SQLException err) {
JOptionPane.showMessageDialog(null, err);
}
}
Column name is must while getting a data
Thanks
Updated following the question change
There is no column name explicitly specified for the calculated column SUM(PRICE) in your SQL statement. It would hardly ever actually be "SUM(PRICE)". Try naming your column. Also prepareStatement is useful when passing parameters. Simple Select does not need it:
private void btnCalculateActionPerformed(java.awt.event.ActionEvent evt) {
try{
String SQL = "SELECT SUM(PRICE) As PRICE_TOTAL FROM MENU";
Statement stmt = con.createStatement();
ResultSet ps = stmt.executeQuery(SQL);
if(ps.next()) {
String total = ps.getString("PRICE_TOTAL");
textTotalCost.setText(total);
}
}
catch (SQLException err) {
JOptionPane.showMessageDialog(null, err);
}
}
or access the value by column index rather than name:
private void btnCalculateActionPerformed(java.awt.event.ActionEvent evt) {
try{
String SQL = "SELECT SUM(PRICE) FROM MENU";
Statement stmt = con.createStatement();
ResultSet ps = stmt.executeQuery(SQL);
if(ps.next()) {
String total = ps.getString(0);
textTotalCost.setText(total);
}
}
catch (SQLException err) {
JOptionPane.showMessageDialog(null, err);
}
}
I don't fully understand your description but I think you are trying to assign the PreparedStatement created in
stmt = con.prepareStatement(SQL)
to a variable of type Statement (stmt) and that's causing the error. The line of code above works because PreparedStatement is an extension (or implementation) of Statement but
ps = stmt.executeQuery();
fails because the class Statement doesn't have an executeQuery method without parameters, PreparedStatement does.
#Y.B.'s solution and the rest of recommendations are good (the alias for sum(price) or getting the value by column index) if it's ok using a regular Statement. The alternative is changing the type of stmt to PreparedStatement in your original code.

How to fix my Prepared Statement to give me data from the DB in my application?

I have my Java program and I need to get data from my MYSQL DB,
I wrote this one out but its just sysout so getting data from my class and not using the Prepared Statement (I can delete the first 3 lines and it will work the same )
Could use some help to figure out how to get data from my DB and print it out
public void viewClientDetails(ClientsBean client) {
try {
PreparedStatement ps = connect.getConnection().prepareStatement(
"SELECT * FROM mbank.clients WHERE client_id = ?");
ps.setLong(1, client.getClient_id());
System.out.println(client.getClient_id());
System.out.println(client.getName());
System.out.println(client.getType());
System.out.println(client.getPhone());
System.out.println(client.getAddress());
System.out.println(client.getEmail());
System.out.println(client.getComment());
} catch (SQLException e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null,
"Problem occurs while trying to see client details");
}
}
Well you're not actually executing the prepared statement... you're just preparing it. You should call PreparedStatement.executeQuery and use the ResultSet it returns:
// ...code as before...
try (ResultSet results = ps.executeQuery()) {
while (results.next()) {
// Use results.getInt etc
}
}
(You should use a try-with-resources statement to close the PreparedStatement too - or a manual try/finally block if you're not using Java 7.)
You need to do executeQuery on the preparedstatement to get a result set back of the query you performed.
You are simply not executing the query. Add a PreparedStatement.executeQuery() call. And fetch the results from the returned ResultSet.
For example:
PreparedStatement ps = connect.getConnection().prepareStatement("SELECT * FROM mbank.clients WHERE client_id = ?");
ps.setLong(1, client.getClient_id());
ResultSet rs = ps.executeQuery();
while (rs.next()) {
String userid = rs.getString("id");
String username = rs.getString("name");
}
As #Jon Skeet pointed out, the declaration of ResultSet in Java 7 is updated to:
public interface ResultSet extends Wrapper, AutoCloseable
It is AutoClosable now, which means that you can and should use the try-with-resource pattern.
You can do the below.
PreparedStatement ps = connect.getConnection().prepareStatement(
"SELECT * FROM mbank.clients WHERE client_id = ?");
resultSet = ps.executeQuery();
while (resultSet.next()) {
String user = resultSet.getString("<COLUMN_1>");
String website = resultSet.getString("<COLUMN_2>");
String summary = resultSet.getString("<COLUMN_3>");
}

java : use of executeQuery(string) method not supported error?

I'm doing a simple preparedstatement query execution and its throwing me this error:
java.sql.SQLException: Use of the executeQuery(string) method is not supported on this type of statement at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.notSupported(JtdsPreparedStatement.java:197) at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeQuery(JtdsPreparedStatement.java:822) at testconn.itemcheck(testconn.java:58)
Any ideas what i'm doing incorrectly? thanks in advance
here is the code:
private static int itemcheck (String itemid ) {
String query;
int count = 0;
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver");
con = java.sql.DriverManager.getConnection(getConnectionUrl2());
con.setAutoCommit(false);
query = "select count(*) as itemcount from timitem where itemid like ?";
//PreparedStatement pstmt = con.prepareStatement(query);
//pstmt.executeUpdate();
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1,itemid);
java.sql.ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
count = rs.getInt(1);
System.out.println(count);
} //end while
}catch(Exception e){ e.printStackTrace(); }
return (count);
} //end itemcheck
A couple of things are worth checking:
Use a different alias. Using COUNT as an alias would be asking for trouble.
The query object need not be passed twice, once during preparation of the statement and later during execution. Using it in con.prepareStatement(query); i.e. statement preparation, is enough.
ADDENDUM
It's doubtful that jTDS supports usage of the String arg method for PreparedStatement. The rationale is that PreparedStatement.executeQuery() appears to be implemented, whereas Statement.executeQuery(String) appears to have been overriden in PreparedStatement.executeQuery() to throw the stated exception.
So...
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1,itemid);
java.sql.ResultSet rs = pstmt.executeQuery(query);
Unlike Statement, with PreparedStatement you pass the query sql when you create it (via the Connection object). You're doing it, but then you're also passing it again, when you call executeQuery(query).
Use the no-arg overload of executeQuery() defined for PreparedStatement.
So...
PreparedStatement pstmt = con.prepareStatement(query);
pstmt.setString(1,itemid);
java.sql.ResultSet rs = pstmt.executeQuery();

Categories

Resources