Generate sql query by anorm, with all nulls except one
我使用play框架2.3.8和scala开发Web应用程序,后端和前端均具有复杂的体系结构。作为后端,我们使用MS SQL和许多存储过程,并由anorm对其进行了调用。这是问题之一。
我需要更新数据库中的某些字段。前端调用play框架,字段的接收名称和值。然后我解析字段名称,然后需要为更新字段生成SQL查询。我需要为所有参数分配null,除了已接收参数。我尝试这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | def updateCensusPaperXX(name: String, value: String, user: User) = { DB.withConnection { implicit c => try { var sqlstring ="Execute [ScXX].[updateCensusPaperXX] {login}, {domain}" val params = List( "fieldName1", "fieldName2", ..., "fieldNameXX" ) for (p <- params){ sqlstring +="," if (name.endsWith(p)) sqlstring += value else sqlstring +="null" } SQL(sqlstring) .on( "login" -> user.login, "domain" -> user.domain, ).execute() } catch { case e: Throwable => Logger.error("update CensusPaper04 error", e) } } } |
但是实际上并非在所有情况下都有效。例如,当我尝试保存字符串时,它给我一个错误,例如:
1 | com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near 'some phrase' |
使用除一个以外的所有空值的anorm生成sql查询的最佳方法是什么?
发生这种情况的原因是,当您将字符串值直接写入SQL语句时,需要将其引起引用。解决此问题的一种方法是确定哪些字段是字符串,并添加条件逻辑以确定是否引用该值。这可能不是解决问题的最佳方法。通常,应该使用命名参数,而不是使用参数值构建字符串。这有一些好处:
这意味着您应该像对待用户和域一样将字段列表视为命名参数。这可以通过对上面的代码进行一些小的更改来完成。首先,您可以按照以下方式构建SQL语句:
1 2 3 4 5 6 7 8 9 |
上面发生的事情是您不需要直接插入值,因此可以通过在查询字符串的末尾添加参数列表来构建字符串。
然后您可以继续并开始构建参数列表。注意,
1 2 3 4 5 6 7 8 9 10 | val userDomainParams: Seq[NamedParameter] = (("login",user.login),("domain",user.domain)) val additionalParams = params.map(p => if (name.endsWith(p)) NamedParameter(p, value) else NamedParameter(p, None) ).toSeq val fullParams = userDomainParams ++ additionalParams // At this point you can execute as follows SQL(sqlString).on(fullParams:_*).execute() |
这里发生的事情是建立参数列表,然后使用splat运算符
这可以解决与字符串有关的问题,因为您不再需要将字符串直接写入查询中,并且具有消除与编写SQL字符串而不是使用参数有关的其他问题的更多好处。