使用SQL插值的ScalikeJDBC的未知SQL语法错误

问题描述 投票:0回答:1

为了避免DRY,我试图创建一个带有可变列名的sql INSERT语句,并通过ScalikeJDBC的sql插值填充这些列的数据:

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? (?,?)VALUES(?,?)

参数是: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"""...""",但这似乎没有什么区别。我可以在我的MySQL工作台GUI中执行预期的语句。知道我的语法错误是什么吗?

mysql scala scalikejdbc
1个回答
0
投票

根据@scaisEdge的提示,似乎ScalikeJDBC在使用其语法时,总是会在任何参数化值周围放置单引号。从这里判断 - https://github.com/scalikejdbc/scalikejdbc/issues/320 - 这是一个众所周知的问题。

使用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()
      }
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.