1

I'm trying to run an insert or update on a table - the string generated from below works fine when copy pasted into HeidiSQL but throws SQLSyntaxErrorExceptions when run from Java:

Statement statement = con.createStatement();
String escapedXML = EscapeString(billboard.getXml());
String sql = String.format(
    "DELIMITER $ \r\nBEGIN NOT ATOMIC\r\n" +
    "IF EXISTS(SELECT * FROM billboards where Name='%s') THEN UPDATE billboards SET XML='%s' where Name='%s';\r\n" +
    "ELSE insert into billboards(Name, XML, CreatorName) values('%s', '%s', '%s');\r\n" +
    "END IF;\r\n" +
    "END $\r\n" +
    "DELIMITER ;", billboard.getName(), escapedXML, billboard.getName(), billboard.getName(), escapedXML, billboard.getCreatorName());
// Insert or update billboard
statement.execute(sql);

I can't figure out why.

GMB
  • 216,147
  • 25
  • 84
  • 135

3 Answers3

0

I would recommend using the insert ... ok duplicate key syntax here rather than a code block. This is more efficient, and implements the lockout a single statement, which should avoid the problem you meet when running the query from your php code.

insert into billboards(Name, XML, CreatorName) 
values(?, ?, ?)
on duplicate key update set XML = values(XML)

For this to work, you need a unique (or primary key) constraint on column Name.

Also, consider using a parameterized query rather than concatenating variables in your query stringW Escaping is inefficient and does not really make your code safer.

GMB
  • 216,147
  • 25
  • 84
  • 135
0

You should have tried NamedParameterStatement with your query to facilitate setting of string parameters and avoid their duplication (using refactored query suggested in GMB's earlier answer):

String sql = "INSERT INTO billboards (Name, XML, CreatorName) VALUES (:name, :xml, :creator) "
             + "ON DUPLICATE KEY UPDATE SET XML = :xml";

NamedParameterStatement statement = new NamedParameterStatement(con, sql);
statement.setString("name", billboard.getName());
statement.setString("xml", EscapeString(billboard.getXml()));
statement.setString("creator", billboard.getCreatorName());

// Insert or update billboard
statement.execute(sql);
Nowhere Man
  • 19,170
  • 9
  • 17
  • 42
0

The reason that you are getting a syntax error is that DELIMITER is a MySQL client command and not an SQL statement. MySQL commands may not be used in with JDBC.

For more information:

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216