Statement works in database, but fails in Java code - - java

CREATE USER Person identified by 2012;GRANT ALL PRIVILEGES TO Person;
These statements are successfully executed by Oracle 11g (GUI). But, when I copy and paste the above statement exactly and try to execute it by using executeUpdate(String sql), I get the exception below. Why?
java.sql.SQLSyntaxErrorException: ORA-00911: invalid character

You should not give a two different SQL statements as one. There is no way that you can JDBC driver will execute two statements passed as one string.
try to execute them as
Statement stmt = conn.createStatement();
stmt.executeUpdate("CREATE USER Person identified by 2012");
stmt.executeUpdate("GRANT ALL PRIVILEGES TO Person;");
That should do. Cheers.

Dependend on your database jdbc driver, the driver will not support executing two statements in one "executeUpdate". You have to do something like:
Statement stmt = conn.createStatement();
for(String statement : statements) {
stmt.addBatch(statement);
}
stmt.executeBatch();

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.)

When I run SQL query from RIDE it gives error

I am having this problem,
When I send an SQL query as an argument it gives error
when I use the same query directly in my java program it works fine.
MY SQL query when I send as an argument is as follow
Select RATINGPERIOD from INVESTMENT.I1INVE Where INVESTMENTID = 100
rs = stmt.executeQuery(sqlQery); // Select RATINGPERIOD from INVESTMENT.I1INVE Where INVESTMENTID = 100
and when I use it directly into my java program is as follow
try
{
// Load the driver
Class.forName("com.ibm.db2.jcc.DB2Driver");
System.out.println("**** Loaded the JDBC driver");
// Create the connection using the IBM Data Server Driver for JDBC and SQLJ
con = DriverManager.getConnection (url, user, password);
// Create the Statement
stmt = con.createStatement();
System.out.println("**** Created JDBC Statement object");
// Execute a query and generate a ResultSet instance
rs = stmt.executeQuery("Select RATINGPERIOD from INVESTMENT.I1INVE where INVESTMENTID = 100");
while (rs.next()) {
delay = rs.getString("RATINGPERIOD");
System.out.println("size of list ="+delay);
}
}
Error log
com.ibm.db2.jcc.am.SqlException: [jcc][10103][10941][3.62.57] Method executeQuery cannot be used for update. ERRORCODE=-4476, SQLSTATE=null
at com.ibm.db2.jcc.am.fd.a(fd.java:660)
at com.ibm.db2.jcc.am.fd.a(fd.java:60)
at com.ibm.db2.jcc.am.fd.a(fd.java:120)
at com.ibm.db2.jcc.am.jn.a(jn.java:4129)
at com.ibm.db2.jcc.am.jn.a(jn.java:2875)
at com.ibm.db2.jcc.am.jn.a(jn.java:679)
at com.ibm.db2.jcc.am.jn.executeQuery(jn.java:663)
at com.profitsoftware.testing.utils.keywords.date.DatabaseSQL.sqlQuery(DatabaseSQL.java:46)
at com.profitsoftware.testing.utils.keywords.date.DatabaseSQLKeywords.executeSqlQuery(DatabaseSQLKeywords.java:18)com.
ok some more information, I have assigned sql query to a string in Java program and then compared it to the query(String) I was getting as argument in my java program and it gives false. which explain maybe when query is passed from RIDE to Java programm it changes somehow. any idea what happens there ?
Thanks in advance and sorry if it sounds a stupid question, I a new to this programming world.
oK, It started to work, actually I was missing something there, so type. My logic itself was good but it was typo that created the problem
--Sara

JDBC doesn't seem to want to call DELETE PreparedStatement when batched for MySQL

When I run the code in non-batch mode it works:
PreparedStatement preparedStatement = connection.prepareStatement(
"DELETE FROM myTable WHERE id=58");
preparedStatement.execute();
However as soon as I try to run it in batch mode:
PreparedStatement preparedStatement = connection.prepareStatement(
"DELETE FROM myTable WHERE id=58");
preparedStatement.executeBatch();
It will no longer delete the entry from the table. All my INSERTS work perfectly well with executeBatch, in fact everything so far except the DELETE command. It doesn't come back with any kind of error, it just seems to ignore the command and skip over it. And if I inspect the number of columns affected by looking at the int[] returned it's empty (int[].length = 0).
Update: I don't believe it's a permission issue because the user account has full root privileges and access to all commands. And if it was a permission issue then it shouldn't work in non-batch mode.
The issue was that for the delete SQL statement for whatever reason I forgot to add the following line:
preparedStatement.addBatch();
Omitting this line means the PreparedStatement was never added to the batch and hence never executed. There are of course no warnings or errors because the SQL statement is never executed, it's just omitted. As there were other SQL batch PreparedStatement in the batch there was no need for an empty batch exception to be thrown (some drivers will throw an exception but this is not guaranteed so don't rely on it).
Therefore the correct code would be:
PreparedStatement preparedStatement = connection.prepareStatement(
"DELETE FROM myTable WHERE id=58");
preparedStatement.addBatch();
preparedStatement.executeBatch();
Now as pointed in a comment you would normally not want to execute a single SQL command with batching, the reason this was done was to isolate the issue to the specific SQL command.

HSQLDB over JDBC: execute SQL statements in batch

I need to initialize a database from my Java application. For reasons of code maintainability, I would like to maintain the SQL code separately from the Java code (it is currently in a separate source file).
The first few lines of the file are as follows:
-- 1 - Countries - COUNTRIES.DAT;
drop table Countries if exists;
create table Countries(
CID integer,
ECC varchar(2),
CCD varchar(1),
NAME varchar(50));
I read the SQL code from the file and store it in a string. Then I do:
PreparedStatement stmt = dbConnection.prepareStatement(sqlString);
This fails with the following exception:
java.sql.SQLSyntaxErrorException: unexpected token: CREATE : line: 2
This looks as if JDBC doesn't like multiple SQL statements in a single PreparedStatement. I have also tried CallableStatement and prepareCall(), with the same result.
Does JDBC provide a way to pass the entire SQL script in one go?
The JDBC standard (and the SQL standard for that matter) assumes a single statement per execute. Some drivers have an option to allow execution of multiple statements in one execute, but technically that option violates the JDBC standard. There is nothing in JDBC itself that supports multi-statement script execution.
You need to separate the statements yourself (on the ;), and execute them individually, or find a third-party tool that does this for you (eg MyBatis ScriptRunner).
You might also want to look at something like flyway or liquibase.
To run a hardcoded / loaded from file queries you can use execute like:
Statement stmt = null;
String query = "drop table Countries if exists;
create table Countries(
CID integer,
ECC varchar(2),
CCD varchar(1),
NAME varchar(50));";
try {
stmt = con.createStatement();
stmt.execute(query);
} catch (SQLException e ) {
JDBCTutorialUtilities.printSQLException(e);
} finally {
if (stmt != null) { stmt.close(); }
}
If you want to run dynamic queries for example to append values you have to use PreparedStatement. For running a query from a file it's not recommended to put dynamic queries in it.

PreparedStatement executing successfully in oracle but throwing exception in Microsoft SQL

I have this below query that I execute using java PreparedStatement:
String dml=insert into users(name, addr, city, sex, dob) values(?,?,?,?,?);
PreparedStatement stmt = conn.prepareStatement(dml);
stmt.setString(1,"abcd");
stmt.setString(2,"def");
stmt.setString(3,"ghij");
stmt.setString(4,"m");
stmt.setString(5,"1-Jan-1987");
stmt.executeQuery();
It executes successfully when the database is Oracle, but when the database is Microsoft SQL, then it throws an exception "java.sql.SQLException: The executeQuery method must return a result set". Could someone please tell what is the issue here. Why is the same query executing successfully in oracle but not in microsft sql?
The answer is in the message - ExecuteQuery requires a result set. Use executeUpdate instead.
From the above Link:
boolean execute() Executes the SQL statement in this PreparedStatement object, which may be any kind of SQL statement.
ResultSet executeQuery() Executes the SQL query in this PreparedStatement object and returns the ResultSet object generated by the query.
int executeUpdate() Executes the SQL statement in this PreparedStatement object, which must be an SQL INSERT, UPDATE or DELETE statement; or an SQL statement that returns nothing, such as a DDL statement.
the fact that it works on oracle is probably just a side effect which you've discovered cannot be relied upon.
If you're performing an INSERT/UPDATE statement, you should be calling stmt.executeUpdate() rather than stmt.executeQuery(). I imagine there's a difference (though I don't know exactly what) between the Oracle and SQL Server drivers you're using that means that one works and the other one doesn't.
try using the method executeUpdate instead of executeQuery.
since the query at hand is not a select-query, it fails. executeQuery is for select-queries, executeUpdate is for insert, delete and update-queries.
There is the problem on stmt.executeQuery();
executeQuery() is used for SELECT sql operation
executeUpdate() is used for INSERT, UPDATE and DELETE sql operation.
your query is for INSERT operation thus please use stmt.executeUpdate();
This depends upon driver that are using and underlying implementation of executeQuery() method. While using Java Prepared statement the underlying implementation allow this but the driver of SQL server doesnot allow this.
Try to use correct method to execute insert statement like executeUpdate().
go trough this links:-
Sql server:- http://msdn.microsoft.com/en-us/library/ms378540%28v=sql.90%29.aspx
Oracle:- http://docs.oracle.com/javase/1.4.2/docs/guide/jdbc/getstart/statement.html
use stmt.execute(); instead of stmt.executeQuery();
stmt.execute(); or executeUpdate(); for INSERT, UPDATE, DELETE (etc.)
stmt.executeQuery(); for SELECT

Categories