Syntax error on Java PreparedStatement.setBytes with mysql - java

I'm trying to set a BLOB mysql field with the PreparedStatement.setBytes method.
The problem is that the query ends up with a string containing the bytes to be inserted.. more or less.
So, here is the code where it's about:
PreparedStatement stmt = this.getStatement( "UPDATE TABLE users SET logintoken=? WHERE qrid=?" );
stmt.setBytes( 1, token );
stmt.setString( 2, bar.getId() );
stmt.execute();
For the record, token is a byte[] always holding 20 bytes generated by SecureRandom
And here is the 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 'TABLE users SET logintoken=x'6DA9D5137B059AE6BCFE7F170693A76CA6484FFB24963BF88AA' at line 1
As you can see, it places an x' at the beginning of the data.
Logically this breaks the query since part of the data is not contained within the string.
I assumed that the PreparedStatement.setBytes would solve the problem but it does not.
I've also tried it with a java.sql Blob object but it more or less gave the same issues.
Is there something i'm missing?

Look at your UPDATE query closely, the TABLE is not necessary. it should just be like
UPDATE users SET logintoken=? WHERE qrid=?
Refer MySQL Documentation for more information.

Related

Avoid ORA-00904 - invalid identifier error while doing sql query in java as the column may or may not be preset in the database

I am trying to write java code to migrate data from oracle database to other database.
My use case is that different client have different version of code and so the database columns may vary. Clients with later version have additional column.
For eg : Client with new version as COL99 in the table SAMPLE_TABLE.
While writing the migration code, if I try to select the COL99 from SAMPLE_TABLE, it will work fine for the new client. But for clients on old version, the code fails with
ORA-00904 Invalid Identifier error.
Is there a way to handle in sql query or java code such that, if the column doesn't exist in the database table, simply ignore and do not return the value instead of throwing the exception.
You should first check, whether COL99 exists for your current database connection.
For Oracle you can use a query like this:
SELECT
COL.COLUMN_ID,
COL.OWNER AS SCHEMA_NAME,
COL.TABLE_NAME,
COL.COLUMN_NAME
FROM
SYS.ALL_TAB_COLUMNS COL
INNER JOIN
SYS.ALL_TABLES T
ON COL.OWNER = T.OWNER
AND
COL.TABLE_NAME = T.TABLE_NAME
WHERE
COL.OWNER = 'SCHEMA'
AND
COL.TABLE_NAME = 'SAMPLE_TABLE'
AND
COL.COLUMN_NAME = 'COL99'
Then you create your query with or without COL99.

Java JDBC SQL Syntax error with PreparedStatement.setTimestamp. Value gets cut off at the colon ':' in time

Whenever I try to execute a prepared statement, it throws a MySQLSyntaxErrorException with:
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 'INSERT INTO Information (stamp) VALUES ('2017-01-24 1' at
**line 1
It looks like it's getting cut off at the colon ":' of the time part of the format.
String sql = "INSERT INTO Information (stamp) VALUES (?);"
...
statement.setTimeStamp(1, new Timestamp(system.currentTimeMillis()));
I've tried a bunch of different ways of getting a system time stamp and converting it to java.sql.Timestamp, but it continues to throw that same error.
My table has a column stamp of type TIMESTAMP.
Ah I found the problem. I didn't realize that prepared statements did not allow multiple queries. My options were to use two statements or add on a connection parameter while sending my connection request
?allowMultipleQueries=true. This allows multiple queries separated by a semi-colon. Thanks yall! –

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.

SQL query works in phpmyadmin but not when using jdbc and java

This query works when I input it through phpmyadmin.
INSERT INTO conversation (user_id) VALUES (?);
INSERT INTO conversation (conversation_id, user_id)
VALUES ((SELECT LAST_INSERT_ID()), ?)
However when I send that query using jdbc and java I get an error -
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 'INSERT INTO conversation (conversation_id, user_id) VALUES ((SELECT LAST_INSERT_' at line 1"
I am using the exact same query. I checked by calling toString on the PreparedStatement and copying and pasting it into phpmyadmin and executing it and it worked fine. It just doesn't work through java. Any ideas whats wrong?
By default, you cannot execute multiple statements in one query through JDBC. Splitting it into two calls will work, as will changing the allowMultiQueries configuration property to True.
JDBC Configuration Properties — allowMultiQueries:
Allow the use of ';' to delimit multiple queries during one statement (true/false), defaults to 'false', and does not affect the addBatch() and executeBatch() methods, which instead rely on rewriteBatchStatements.
Default value: false

Categories

Resources