JDBC throws MySQL syntax Exception, despite valid query - java

Hello helpful folks,
I've a small part in an application which creates a new db schema based on a mysqldump.
The relevant part looks like this:
log.info("= setup basic database");
// Execute each command in the dump
for (String query : dump.split(";")) {
statement.execute(query);
}
This works fine but some statements just break with something like
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 ''ot_subtotal.php' at line 1
The query in this case is
INSERT INTO `configuration` VALUES (194,'MODULE_ORDER_TOTAL_INSTALLED','ot_subtotal.php;ot_discount.php;ot_coupon.php;ot_shipping.php;ot_cod_fee.php;ot_gv.php;ot_subtotal_no_tax.php;ot_tax.php;ot_total_netto.php;ot_total.php',6,0,NULL,'2016-06-17 15:27:24',NULL,NULL);
If I replace the string "'ot_subtotal.php;ot_discount.php;ot_coupon.php;ot_shipping.php;ot_cod_fee.php;ot_gv.php;ot_subtotal_no_tax.php;ot_tax.php;ot_total_netto.php;ot_total.php'" with something like "hello world" it works and breaks at a another query later on.
The thing is, I'm able to import the dump via the terminal command "mysql ... < dump.sql" without a problem.
Any ideas?

This is happening because of
for (String query : dump.split(";")) {
statement.execute(query);
}
You are splitting at ; which result in incomplete queries.
For example:
INSERT INTO `configuration` VALUES (194,'MODULE_ORDER_TOTAL_INSTALLED','ot_subtotal.php;ot_discount.php;ot_coupon.php;ot_shipping.php;ot_cod_fee.php;ot_gv.php;ot_subtotal_no_tax.php;ot_tax.php;ot_total_netto.php;ot_total.php',6,0,NULL,'2016-06-17 15:27:24',NULL,NULL);
Above query after split at ; will be
INSERT INTO `configuration` VALUES (194,'MODULE_ORDER_TOTAL_INSTALLED','ot_subtotal.php
Which is incorrect.

Instead of
dump.split(";")
Use
dump.split(";\n")
If you created the dump file in normal way.

Related

Liquibase run store procedure returns error

I try to set up the sql file from changeset to run a store procedure that is saved into my project but it returns sql error.
Here I declared the sqlfile:
<sqlFile path="/db/FindAllFriends.sql" endDelimiter="//" relativeToChangelogFile="true" splitStatements="true" stripComments="true" />
Here is my procedure:
DELIMITER //
CREATE PROCEDURE aaa()
BEGIN
END //
DELIMITER ;
If I let the "delimiter" in script it will return an sql error (you have an error in your sql syntax; check the manual....). If I remove it, it will be ok but it works only with ";" delimiter.
If I tried to drop and then create the procedure (or multiple statements):
Drop procedure if exists aaa;
CREATE PROCEDURE aaa()
BEGIN
END;
I receive: Error executing sql drop procedure if exists aaa;
My problem is that I need first to "drop procedure if exists" and after to create it, and I'm forced to use "delimiter" inside of script.
I don't know if it is a problem with the mysql parser, liquibase error or I made a mistake in my script.
I'm struggling with procedures (on Oracle) for some time now, and I start to believe that Liquibase was not made with procedures in mind ;)
Anyway - maybe dropProcedure and createProcedure changes would be sufficient for you?
I find executeCommand change with sqlplus to be the best solution to run scripts on Oracle...
Finally I was able run all scripts; I don't know what I made wrong when I tried first time, but now works. I had to declare the endDelimiter in sqlFile and to use this delimiter into script, also I deleted the declaration of "Delimiter //" from script

Using a Java method in an SQL Query

I made a program to parse an XML file with, and now I want to put the data in a database,
a PostgreSQL database. However, I cannot use
executeUpdate(INSERT INTO Titles(name) VALUES (parseTitles())),
since it wants a boolean. The string that comes out of the function looks like this:
'a','b','c','d'
Is there a way to solve this, or am I bound to put all the data in manually?
java runs first and then the SQL statement is sent to the db to be executed.
You probably need something like this to produce the right sql statement:
executeUpdate( "INSERT INTO Titles(name) VALUES (" + parseTitles() + ")" );

A query works in SQL*Plus but fails in JDBC with an ORA-00911 exception

I'm trying to track the amount of redo being generated during a database session with the following query:
SELECT a.name, b.VALUE
FROM v$statname a, v$mystat b
WHERE a.statistic# = b.statistic# AND a.name = 'redo size';
This query works directly in SQL*Plus and Toad, but I get an ORA-00911 exception using JDBC, and I've narrowed it down to the "statistic#" column name.
How do I get around this?
The column name statistic# is not the problem.
My bet is that you also send the terminating ; from inside your Java program.
But you may not include the the ; when executing a SQL statement through JDBC (at least not in Oracle and some other DBMS).
Remove the ; from your SQL String and it should be fine.
put it in double quotes - that should let you call a field anything in Oracle
Switch on JDBC logging, check your driver documentation for how to do this. In the JDBC log you see the actual statement prepared and executed in the DB. This eliminates one possible cause for the error.

Many delete queries in single JDBC query

I'm having a problem with in my class with generating delete command:
private String generateDeleteCommand() {
StringBuilder deleteCommand = new StringBuilder();
for (ForeignKey fk : exportedForeignKeys) {
deleteCommand.append("DELETE FROM ").append(fk.foreignTableName)
.append(" WHERE ").append(fk.foreignColumnName)
.append("=:").append(fk.primaryColumnName).append(";\n");
}
deleteCommand.append("DELETE FROM ").append(tableName)
.append(" WHERE ");
for (String key : primaryKeys.keySet()) {
deleteCommand.append(key).append("=:").append(key).append(" AND ");
}
deleteCommand
.delete(deleteCommand.length() - 5, deleteCommand.length());
deleteCommand.append(";");
System.out.println(deleteCommand);
return deleteCommand.toString();
}
The query I get is valid when using in phpmyadmin - but when I'll try to use it with jdbc executeUpdate() i get MySQLSyntaxError, i.e. for table "trasy" with two exported foreign keys query looks like:
DELETE FROM kursy WHERE ID_TRASY=19;
DELETE FROM przystanki WHERE ID_TRASY=19;
DELETE FROM trasy WHERE ID_TRASY=19;
Exception:
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 'DELETE FROM przystanki WHERE ID_TRASY=19;
DELETE FROM trasy WHERE ID_TRASY=19' at line 2
It doesn't matter whether there is \n between the queries or no.
Use the .addBatch() method on Statement and add each DELETE query separately and .executeBatch() them as a batch.
If using transactions, you can test the counts returned by each statement, and if anything is wrong, you can .rollback() the entire batch.
I have an open source project that shows exactly how to do this.
SQL Construction Kit on GitHub, there is an AbstractDatabase.java class that has an .executeBatch() method that you can copy and use yourself with very little modification. It even has the code for testing each command and doing the commit/rollback.
jdbc executes one statement at a time, so your statements, even if are multiple seperated by \n, are in fact executed as one instruction hence the error from mysql.

SELECT * FROM table throws error in JDBC

I am trying to make a select from a table, which works fine with every other table in my database, but when I try the following I recieve an error:
db.makeQuery("SELECT * FROM References");
Which calls:
public ResultSet makeQuery(String query) throws Exception
{
preparedStatement = connect.prepareStatement(query);
resultSet = preparedStatement.executeQuery(query);
return resultSet;
}
It then throws the following error:
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 'References' at line 1
I seems very strange to me, since this statement works:
db.makeQuery("select * from Products");
References is a keyword in SQL, so you better avoid it for table names. (See for instance this documentation.)
As suggested by Nishant, you can use reserved words in queries if you escape them with backticks.
Related question:
Using MySQL keywords in a query?
use
db.makeQuery("SELECT * FROM `References`");
if you can, better, avoid having names that are MySQL keywords. As suggested by aioobe
You might be misspelling the name of your table. MySQL gives this error when it can't find that table you're referring to.
Use SHOW TABLES; to see the names of the tables in your database, and double-check the name.

Categories

Resources