Неизвестная синтаксическая ошибка SQL для ScalikeJDBC с SQL-интерполяцией

0

Чтобы избежать 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. Любая идея, что моя синтаксическая ошибка?

Теги:
scalikejdbc

1 ответ

0
Лучший ответ

Исходя из подсказки @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()
      }
    }
  }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню