MySQLSyntaxErrorException error in Like clause - java

I have this function, which gets a List of objects from MySQL, using the like clause, but when testing, returns me a error of MySQLSyntaxErrorException, what i should do?
Code
#Override
public List<Livro> getLista(String nm) {
// TODO Auto-generated method stub
List<Livro> lista = new ArrayList<Livro>();
try {
String query= "SELECT L.*, nmautor, nmeditora FROM tblivro L, tbeditora E,tbautor A "
+ "WHERE nmlivro LIKE ? and L.cdautor = A.cdautor and L.cdeditora = E.cdeditora ";
PreparedStatement stmt = conn.prepareStatement(query);
String like = "%"+nm+"%";
stmt.setString(1, like);
ResultSet rs = stmt.executeQuery(sql);
...
}}
Full Error
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'a' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:404)
at com.mysql.jdbc.Util.getInstance(Util.java:387)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:941)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3870)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3806)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2470)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2617)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2546)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2504)
at com.mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1370)
at biblioc.dados.LivroDAO.getLista(LivroDAO.java:387)

The error is in this line:
ResultSet rs = stmt.executeQuery(sql);
Replace this with
ResultSet rs = stmt.executeQuery();
To execute a SQL string with JDBC, you only need to pass the SQL string to JDBC once, and when you are using a PreparedStatement that one time is when you prepare the statement. Once you've set all the parameters, calling executeQuery() with no arguments will run the prepared statement with the parameter values you set.
Calling the version of executeQuery that takes a single string parameter will run the SQL in that string, without allowing you to use any parameter values. This is because the PreparedStatement interface inherits this method from the Statement interface.
This behaviour of the MySQL JDBC driver is particularly confusing. You are far from being the first person to make this mistake and wonder what is going on, and I cannot believe that you will be the last. As pointed out in the comments, the JDBC driver is supposed to throw an exception when you call executeQuery with a string on a PreparedStatement. Had it done so, you may well have found a solution to your problem much quicker.
I don't know what your variable sql is. Perhaps it just contains a single letter a - I was able to reproduce your error message by running stmt.executeQuery("a").

Related

java.sql.SQLSyntaxErrorException when inserting into MySQL database using PreparedStatement [duplicate]

I'm trying to execute a query using a PreparedStatement in Java.
I am getting error number 1064 when I try to execute my query (syntax error).
I have tested this in MySQL query browser with substituted values which works fine.
What's wrong with my code?
Here's the relevant code:
String query = "select MemberID, MemberName from members where MemberID = ? or MemberName = ?";
Connection conn = DriverManager.getConnection(DATABASE_URL, USERNAME, PASSWORD);
PreparedStatement s = conn.prepareStatement(query);
s.setInt(1, 2);
s.setString(2, "zen");
ResultSet rs = s.executeQuery(query);
Here's the exception I'm getting:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near '? or MemberName
= ?' at line 1
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? or MemberName = ?' at line 1
MySQL doesn't understand the meaning of ? in the SQL query. It's indeed invalid SQL syntax. So somehow it's not been replaced by PreparedStatement. And guess what?
PreparedStatement s = conn.prepareStatement(query);
s.setInt(1, intValue);
s.setString(2, strValue);
rs = s.executeQuery(query); // Fail!
You're overridding the prepared query with the original query! You need to call the argumentless PreparedStatement#executeQuery() method instead of Statement#executeQuery(String).
PreparedStatement s = conn.prepareStatement(query);
s.setInt(1, intValue);
s.setString(2, strValue);
rs = s.executeQuery(); // OK!
Unrelated to the problem, your code is leaking resources. The DB will run out of them after several hours and your application will crash. To fix this, you need to follow the JDBC idiom of closing Connection, Statement and ResultSet in the finally block of the try block where they're been acquired. Check the JDBC basic tutorial for more detail.
If you look at the javadocs for Statement (the superclass of PreparedStatement), the method docs for executeQuery(String) and executeUpdate(String) say this:
Note: This method cannot be called on a PreparedStatement or CallableStatement.
That's what you are doing here: calling executeQuery(String) from Statement on a PreparedStatement object.
Now since the javadocs say that you "cannot" do this, actual behavior you get is unspecified ... and probably JDBC driver dependent. In this case, it appears that the MySQL driver you are using is interpreting this to mean that you are doing the update as a non-prepared statement, so that the ? tokens are NOT interpreted as parameter placeholder. That leads the server-side SQL parser to say "syntax error".
(It would be easier for programmers if a different unchecked exception was thrown by the MySQL driver if you did this; for example UnsupportedOperationException. However, the standard JDBC javadocs don't say what should happen in this situation. It is up to the vendor what their drivers will do.)

What is reason for following sql code couldn't insert data?

My database have two column. One column is auto increment id(Primary Key) and other is 'Sentence' column. Manually type something and I can insert that value. But when I'm trying insert variable value that gives error message. I tried different ways. ('?') /( ? )/(?) Not work anything for me.
int s1=9;
String s2="Kasuni";
String sql = "INSERT INTO sentences (Sentence) VALUES ( ? )";
PreparedStatement pstmtJ = conn.prepareStatement(sql);
//pstmtJ.setInt(1, s1);
pstmtJ.setString(1,s2);
pstmtJ.executeUpdate(sql);
1st value I didn't insert because of that is auto increment value. I just comment and that shows in my above code.
Error message:
Exception in thread "main" com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? )' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
at java.lang.reflect.Constructor.newInstance(Unknown Source)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1030)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3558)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3490)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1959)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2109)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2642)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1647)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1566)
at TestJsoup.main(TestJsoup.java:66)
When I'm tring following code:
int s1=9;
String s2="Kasuni";
String sql = "INSERT INTO sentences (Sentence) VALUES ('?')";
PreparedStatement pstmtJ = conn.prepareStatement(sql);
//pstmtJ.setInt(1, s1);
pstmtJ.setString(1,s2);
pstmtJ.executeUpdate(sql);
That gives following error messages:
Exception in thread "main" java.sql.SQLException: Parameter index out of range (1 > number of parameters, which is 0).
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
at com.mysql.jdbc.PreparedStatement.checkBounds(PreparedStatement.java:3646)
at com.mysql.jdbc.PreparedStatement.setInternal(PreparedStatement.java:3630)
at com.mysql.jdbc.PreparedStatement.setString(PreparedStatement.java:4481)
at TestJsoup.main(TestJsoup.java:65)
pstmtJ.executeUpdate(sql); → You're sending the original SQL string, since that is calling Statement.executeUpdate(String).
Use pstmtJ.executeUpdate(); instead (PreparedStatement.executeUpdate()) to execute the prepared statement.
Interface Statement
int executeUpdate(String sql)
Executes the given SQL statement, which may be an INSERT, UPDATE, or DELETE statement or an SQL statement that returns nothing, such as an SQL DDL statement. refer java doc
public interface PreparedStatement extends Statement
int executeUpdate()
Executes the SQL statement in this PreparedStatement object, which must be an SQL Data Manipulation Language (DML) statement, such as INSERT, UPDATE or DELETE; or an SQL statement that returns nothing, such as a DDL statement.refer java doc
you are calling executeUpdate(String sql) which is from Statement interface, you have to call executeUpdate() from PreparedStatement interface to resolve issue.
Modified Code :
int s1=9;
String s2="Kasuni";
String sql = "INSERT INTO sentences (Sentence) VALUES ( ? )";
PreparedStatement pstmtJ = conn.prepareStatement(sql);
//pstmtJ.setInt(1, s1);
pstmtJ.setString(1,s2);
pstmtJ.executeUpdate();

MySQL update works, but not when used in PreparedStatement

Can't figure this out. Everything looks good, but I keep getting a MySQLSyntaxErrorException when it's run.
public static void setSupervisorApproval(HttpServletRequest request) throws ClassNotFoundException, SQLException {
String requestID = request.getParameter("txtRequestId");
boolean approved = request.getParameter("ckbApprove") != null;
Connection conn = getConnection();
Date approveDate = new Date();
String query = "UPDATE request SET isApproved=?, approverDate=?, approver=?, comments=? where id=?;";
PreparedStatement ps = conn.prepareStatement(query);
ps.setBoolean(1, approved);
ps.setDate(2, new java.sql.Date(approveDate.getTime()));
ps.setInt(3, Integer.parseInt(request.getParameter("txtUser")));
ps.setString(4, request.getParameter("taComments"));
ps.setInt(5, Integer.parseInt(requestID));
System.out.println(ps);
ps.executeUpdate(query);
ps.close();
conn.close();
}
When the method is run, the query looks fine. For example, one such result is:
UPDATE request SET isApproved=1, approverDate='2014-11-19', approver=80, comments='This is a comment.' where id=1;
which will work as an update query in the MySQL command line. However, I get this error when it runs in Java:
An error has occurred: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?, approverDate=?, approver=?, comments=? where id=?' at line 1.
Anybody else run into this and have a fix?
EDIT: I understand (after proofreading my page) that I use "request" for both the table name and the HttpServletRequest variable name. As it doesn't affect this question, I'll fix that later.
EDIT 2: Updated the real code. Had originally taken it from some test code that I had modified to test which variable was causing it to barf.
You have called the executeUpdate(String) method, which is inherited from Statement and does not execute your prepared statement with placeholder variables, which explains why you get the ? is invalid syntax error message.
Call executeUpdate() instead, which is defined in PreparedStatement and does what you intended.
Also, as has been pointed out already, number your parameters 1-5 in order in your calls to setXyz methods.

Scrollable ResultSet JDBC Postgresql

When I create a prepared statement like this in java (using JDBC):
pStmt = conn.prepareStatement(qry);
everything works ok. However when I want a scrollable resultset and use this:
pStmt = conn.prepareStatement(qry,ResultSet.TYPE_SCROLL_INSENSITIVE);
I get a syntax error:
org.postgresql.util.PSQLException: ERROR: syntax error at or near "RETURNING"
I'm not even using RETURNING in my query.
Any ideas?
Any help would be appreciated. Thanks
Update:
It seems to work if I use this:
pStmt = db.prepareStatement(qry,ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
What is the difference between SENSITIVE and INSENSITIVE?
Thanks
The second parameter to prepareStatement should be one of Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS.
I guess you want to use
PreparedStatement prepareStatement(String sql,
int resultSetType,
int resultSetConcurrency)
ResultSet.TYPE_SCROLL_INSENSITIVE : This assumes that the result set does not “sense” database changes that occurred after execution of the query.
ResultSet.TYPE_SCROLL_SENSITIVE : picks up changes in the database that occurred after execution of the query

MySQLSyntaxErrorException near "?" when trying to execute PreparedStatement

I'm trying to execute a query using a PreparedStatement in Java.
I am getting error number 1064 when I try to execute my query (syntax error).
I have tested this in MySQL query browser with substituted values which works fine.
What's wrong with my code?
Here's the relevant code:
String query = "select MemberID, MemberName from members where MemberID = ? or MemberName = ?";
Connection conn = DriverManager.getConnection(DATABASE_URL, USERNAME, PASSWORD);
PreparedStatement s = conn.prepareStatement(query);
s.setInt(1, 2);
s.setString(2, "zen");
ResultSet rs = s.executeQuery(query);
Here's the exception I'm getting:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an
error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near '? or MemberName
= ?' at line 1
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? or MemberName = ?' at line 1
MySQL doesn't understand the meaning of ? in the SQL query. It's indeed invalid SQL syntax. So somehow it's not been replaced by PreparedStatement. And guess what?
PreparedStatement s = conn.prepareStatement(query);
s.setInt(1, intValue);
s.setString(2, strValue);
rs = s.executeQuery(query); // Fail!
You're overridding the prepared query with the original query! You need to call the argumentless PreparedStatement#executeQuery() method instead of Statement#executeQuery(String).
PreparedStatement s = conn.prepareStatement(query);
s.setInt(1, intValue);
s.setString(2, strValue);
rs = s.executeQuery(); // OK!
Unrelated to the problem, your code is leaking resources. The DB will run out of them after several hours and your application will crash. To fix this, you need to follow the JDBC idiom of closing Connection, Statement and ResultSet in the finally block of the try block where they're been acquired. Check the JDBC basic tutorial for more detail.
If you look at the javadocs for Statement (the superclass of PreparedStatement), the method docs for executeQuery(String) and executeUpdate(String) say this:
Note: This method cannot be called on a PreparedStatement or CallableStatement.
That's what you are doing here: calling executeQuery(String) from Statement on a PreparedStatement object.
Now since the javadocs say that you "cannot" do this, actual behavior you get is unspecified ... and probably JDBC driver dependent. In this case, it appears that the MySQL driver you are using is interpreting this to mean that you are doing the update as a non-prepared statement, so that the ? tokens are NOT interpreted as parameter placeholder. That leads the server-side SQL parser to say "syntax error".
(It would be easier for programmers if a different unchecked exception was thrown by the MySQL driver if you did this; for example UnsupportedOperationException. However, the standard JDBC javadocs don't say what should happen in this situation. It is up to the vendor what their drivers will do.)

Categories