【发布时间】:2015-01-10 00:46:39
【问题描述】:
我们正在使用 Scala Play,我正在努力确保所有 SQL 查询都使用 Anorm 的字符串插值。它适用于某些查询,但许多查询实际上并没有在查询执行之前替换变量。
import anorm.SQL
import anorm.SqlStringInterpolation
object SecureFile
{
val table = "secure_file"
val pk = "secure_file_idx"
...
// This method works exactly as I would hope
def insert(secureFile: SecureFile): Option[Long] = {
DBExec { implicit connection =>
SQL"""
INSERT INTO secure_file (
subscriber_idx,
mime_type,
file_size_bytes,
portal_msg_idx
) VALUES (
${secureFile.subscriberIdx},
${secureFile.mimeType},
${secureFile.fileSizeBytes},
${secureFile.portalMsgIdx}
)
""" executeInsert()
}
}
def delete(secureFileIdx: Long): Int = {
DBExec { implicit connection =>
// Prints correct values
println(s"table: ${table} pk: ${pk} secureFileIdx: ${secureFileIdx} ")
// Does not work
SQL"""
DELETE FROM $table WHERE ${pk} = ${secureFileIdx}
""".executeUpdate()
// Works, but unsafe
val query = s"DELETE FROM ${table} WHERE ${pk} = ${secureFileIdx}"
SQL(query).executeUpdate()
}
}
....
}
在 PostgreSQL 日志中,很明显 delete 语句没有获取正确的值:
2015-01-09 17:23:03 MST ERROR: syntax error at or near "$1" at character 23
2015-01-09 17:23:03 MST STATEMENT: DELETE FROM $1 WHERE $2 = $3
2015-01-09 17:23:03 MST LOG: execute S_1: ROLLBACK
我尝试了许多不同的 execute、executeUpdate 和 executeQuery,结果相似。目前,我们正在使用基本的字符串替换,但这当然不好,因为它没有使用 PreparedStatements。
【问题讨论】:
-
对Anorm插值、标准Scala插值和PreparedStatement存在误解。
标签: scala playframework-2.3 anorm