This question already has answers here:
Using Prepared Statements to set Table Name
(8 answers)
Closed 6 years ago.
this is my current java program. I need to make a prepared statement and connect to a MySql database.
try {
Connection connect = DriverManager.getConnection(host, username, password);
System.out.println("works fine connected");
/*
*
* */
String Dquery = ("SELECT * FROM ?");
//create the java statement
PreparedStatement st = connect.prepareStatement(Dquery);
st.setString(1, "lmgs_Book");
System.out.println("mySql statemnt: "+Dquery);
//execute the query, and get a java resultset
ResultSet rs = st.executeQuery();
//iterate through the java resultset
while (rs.next())
{
String id = rs.getString(Column1);
String firstName = rs.getString(Column2);/*
String lastName = rs.getString(Column3);
String dateCreated = rs.getString(Column4);
int isAdmin = rs.getInt (Column5);*/
//print the results
System.out.println(id+"|\t"+firstName/*+"|\t\t"+lastName+"|\t\t"+dateCreated+"|\t"+isAdmin*/);
}
st.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I cant insert the "lmgs_Book" String into the prepared statement.
Prepared statement is for the column values not for table name.
But you can use placeholder in place of table name and then replacing
that with your tablename.
String Dquery = ("SELECT * FROM $tableName");
Dquery = Dquery.replace("$tableName","lmgs_Book");
PreparedStatement st = connect.prepareStatement(Dquery);
Remove this:
st.setString(1, "lmgs_Book");
Caution:
And what is the advantage compared to
String Dquery = "SELECT * FROM lmgs_Book";? [Recommended]
Answer: No advantage at all. You may embrace potential harms if you use placeholder in table name like above.
(especially since you should not use a variable in the replace call
instead of the literal, since that might make the statement vulnerable
to SQL injection)
try this and Please make sure your queryString column Name must be a varchar in your database.
String Dquery = ("SELECT * FROM tablename where column_name =?");
//create the java statement
PreparedStatement st = connect.prepareStatement(Dquery);
st.setString(1, "lmgs_Book"); //this line will be set Imgs Books as search Parameter.
Related
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.
I have a strange problem. I have a database and I want to change the values of a column. The values are safed in an Arraylist (timelist).
In order to write the values in the right row, I have a second Arrylist (namelist). So I want to read the first row in my Database, than I check the namelist and find the name. Than i take the matching value out of the timelist and write it into the database into the column "follows_date" in the row, matching to the name.
And than I read the next row of the Database, until there are no more entries.
So the strange thing is, if I change nothing in the database, the while(rs.next()) part works.
For example:
ResultSet rs = statement.executeQuery("SELECT username FROM users");
while(rs.next()){
// read the result set
String name = rs.getString("username");
System.out.println("username = " + name); //liest die namen
}
}
This would print me every name after name. But when I change the table, the while loop ends after that. (no error, the program just finishes)
ResultSet rs = statement.executeQuery("SELECT username FROM users");
while(rs.next()){
// read the result set
String name = rs.getString("username");
System.out.println("username = " + name); //writes the name
//look, if name is in Arraylist "namelist"). if yes, than write the matching date from "timelist" into the database.
if (namelist.contains(name)){
System.out.println("name found: "+ name);
int listIndizi = namelist.indexOf(name); //get index
Long indiziDatum = (long) timelist.get(listIndizi); //get date from same Index
System.out.println(indiziDatum); // print date so i can see it is correct (which it is)
statement.executeUpdate("UPDATE users SET follows_date ="+ indiziDatum +" WHERE username = '"+name+"'"); //updates the follows_date column
}
}
Everything works fine, except that now, the while loop doesn't continues after the first passage, but ends.
The resultSet of a statement is closed and will not return further results if you execute another statement. Create a new separate statement object for the update and everything should work as excepted.
Statement statement1 = connection.createStatement();
Statement statement2 = connection.createStatement();
ResultSet resultSet1 = statement1.executeQuery("SELECT username FROM users");
while(resultSet1.next()){
...
statement2.executeUpdate("UPDATE users ..."));
}
As to Why it happens:
Here is the explanation from the official documentation:
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.
Alternative Approach:
From your sample, it seems you are trying to update the "same" row in your resultSet, you should consider using an Updatable ResultSet.
Sample code from the official documentation:
public void modifyPrices(float percentage) throws SQLException {
Statement stmt = null;
try {
stmt = con.createStatement();
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
ResultSet uprs = stmt.executeQuery(
"SELECT * FROM " + dbName + ".COFFEES");
while (uprs.next()) {
float f = uprs.getFloat("PRICE");
uprs.updateFloat( "PRICE", f * percentage);
uprs.updateRow();
}
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
if (stmt != null) { stmt.close(); }
}
}
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.
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.
How to write a Java prepared statement for MySQL so that it would pick a row containing the highest Timestamp value from a column that would be greater from given parameter?
I got as far as:
SELECT * FROM table WHERE timestamp_col=(SELECT MAX(timestamp_col) FROM table)
But how to convert it to prepared statement?
Since there's not really a parameter, it's pretty simple:
Connection con = null;
PreparedStatement prest;
try{
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://<server>:3306/<db>","<login>","<pass>");
try{
String sql = "SELECT * FROM table WHERE timestamp_col=(SELECT MAX(timestamp_col) FROM table)";
prest = con.prepareStatement(sql);
// prest.setInt(1,12000); // example of using a parameter for prepared statement
// parameters go in the SQL as ?
ResultSet rs1 = prest.executeQuery();
} catch( SQLException s ) { /* etc */ }
You don't need a parameter if you're just asking for a MAX(). It's perfectly safe.