Ошибка в синтаксисе SQL при запуске SQL в Java, но не в HeidiSQL - PullRequest
1 голос
/ 30 мая 2020

Я пытаюсь запустить insert или update в таблице - строка, сгенерированная ниже, работает нормально, когда копия вставлена ​​в Heidi SQL, но выдает SQLSyntaxErrorExceptions, когда запустить из 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);

Не могу понять почему.

Ответы [ 3 ]

0 голосов
/ 30 мая 2020

Вы должны были попробовать NamedParameterStatement с вашим запросом, чтобы упростить настройку строковых параметров и избежать их дублирования (с использованием рефакторинга запроса, предложенного в более раннем ответе GMB ):

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);
0 голосов
/ 30 мая 2020

Причина, по которой вы получаете синтаксическую ошибку, заключается в том, что DELIMITER - это клиентская команда MySQL, а не инструкция SQL. Команды MySQL нельзя использовать с JDB C.

Для получения дополнительной информации:

0 голосов
/ 30 мая 2020

Я бы рекомендовал использовать здесь синтаксис insert ... ok duplicate key, а не блок кода. Это более эффективно и реализует блокировку с помощью одного оператора, что должно избежать проблемы, с которой вы сталкиваетесь при выполнении запроса из вашего php кода.

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

Чтобы это работало, вам нужен уникальный ( или первичный ключ) для столбца Name.

Также рассмотрите возможность использования параметризованного запроса вместо объединения переменных в строке запросаW Экранирование неэффективно и не делает ваш код более безопасным.

...