Чтобы избежать DRY, я пытаюсь создать оператор sql INSERT с именами переменных столбцов и данными для заполнения этих столбцов с помощью интерполяции sql-массива ScalikeJDBC:
case class MySQLInsertMessage(tableName:String, columns:List[String], values:List[String])
def depositMessage(msg: MySQLInsertMessage): Unit = {
NamedDB('MySQLMsgDepositor) localTx { implicit session =>
val sqlStmt = sql"INSERT INTO ${msg.tableName} (${msg.columns}) VALUES (${msg.values})"
println("The sql statement is: " + sqlStmt.statement)
println("The parameters are: " + sqlStmt.parameters)
sqlStmt.update().apply()
}
}
И когда я это называю:
depositMessage(MySQLInsertMessage("My_Table", List("key", "email"), List("42", "[email protected]")))
итоговая распечатка консоли:
Заявление sql: INSERT INTO? (?,?) ЦЕННОСТИ (?,?)
Параметры: List (My_Table, key, email, 42, [email protected])
У вас есть ошибка в синтаксисе SQL; проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с '' My_Table '' ('key', 'email') VALUES ('42', 'user @emai' в строке 1 java.sql.SQLSyntaxErrorException: У вас есть ошибка в синтаксисе SQL, проверьте руководство, соответствующее версии вашего сервера MySQL, для правильного синтаксиса для использования рядом с 'My_Table' ('key', 'email') VALUES ('42', 'user @emai' в строке 1
Я пробовал обернуть sql"..."
как таковой: sql"""..."""
, но это, похоже, не имеет значения. Я могу выполнить ожидаемый оператор очень хорошо в моем графическом интерфейсе Workbench MySQL. Любая идея, что моя синтаксическая ошибка?
Исходя из подсказки @scaisEdge, кажется, что ScalikeJDBC при использовании своего синтаксиса всегда будет размещать одинарные кавычки вокруг любых параметризованных значений. И, судя по всему, https://github.com/scalikejdbc/scalikejdbc/issues/320 - это известная проблема.
С помощью INSERT
MySQL INSERT
(или других) значения табличного имени или столбца могут иметь одинарные кавычки вокруг них, хотя им разрешено иметь обратные ссылки.
Вы можете использовать их SQLSyntax.createUnsafely(str:String)
, или, если бы я хотел сделать это, как я делал выше, вместо использования sql"..."
, я мог бы использовать старый способ SQL(s"INSERT INTO ${msg.tableName} (${msg.columns.mkString(",")})")
Примечание. Я считаю, что оба эти варианта оставляют вас открытыми для инъекционных атак. Поскольку для меня это локальный API, и вам нужно будет иметь имя пользователя и пароль БД, независимо от того, использовать его, я собираюсь с createUnsafely
способом делать что-то с небольшим регулярным выражением "чище" для немного неэлегантного часть разума:
def depositMessage(msg: MySQLInsertMessage): Unit = {
NamedDB('MySQLMsgDepositor) localTx { implicit session =>
val unsafeSQLRegex = "[''\"]".r
val table = SQLSyntax.createUnsafely(s"'${unsafeSQLRegex.replaceAllIn(msg.tableName, "")}'")
val columns = SQLSyntax.createUnsafely(msg.columns.map(value => unsafeSQLRegex.replaceAllIn(value, "")).mkString("'", "', '", "'"))
val sqlStmt = sql"INSERT INTO $table ($columns) VALUES (${msg.values})".update().apply()
}
}
}
Any idea what my syntax error is?
Когда использовать одинарные, двойные и обратные тики в MySQL