这里有一个类似的问题,但实际上并没有回答这个问题.
请注意,这实际上是更大,更复杂的查询的一部分,所以我需要使用普通的sql而不是光滑的提升嵌入.像下面这样的东西会很好:
val ids = List(2,4,9)
sql"SELECT * FROM coffee WHERE id IN ($ids)"
Run Code Online (Sandbox Code Playgroud)
Ben*_*ich 13
该sql前缀解锁StringContext,您可以设置SQL参数.列表没有SQL参数,因此如果您不小心,可以轻松地在此处打开自己的SQL注入.有一些很好的(和一些危险的)关于处理这个问题的SQLServer上建议这个问题.你有几个选择:
你最好的选择可能是使用#$运算符mkString来插入动态SQL:
val sql = sql"""SELECT * FROM coffee WHERE id IN (#${ids.mkString(",")})"""
Run Code Online (Sandbox Code Playgroud)
这没有正确使用参数,因此可能对SQL注入和其他问题持开放态度.
另一种选择是使用常规字符串插值并mkString构建语句:
val query = s"""SELECT * FROM coffee WHERE id IN (${ids.mkString(",")})"""
StaticQuery.queryNA[Coffee](query)
Run Code Online (Sandbox Code Playgroud)
这与使用方法基本相同#$,但在一般情况下可能更灵活.
如果SQL注入漏洞是一个主要问题(例如,如果ids用户提供的元素),您可以使用参数为每个元素构建一个查询ids.然后,您需要提供一个自定义SetParameter实例,以便光滑可以转换List为参数:
implicit val setStringListParameter = new SetParameter[List[String]]{
def apply(v1: List[String], v2: PositionedParameters): Unit = {
v1.foreach(v2.setString)
}
}
val idsInClause = List.fill(ids.length)("?").mkString("(", ",", ")")
val query = s"""SELECT * FROM coffee WHERE id IN ($idsInClause)"""
Q.query[List[String], String](query).apply(ids).list(s)
Run Code Online (Sandbox Code Playgroud)
既然你ids是Ints,这可能不是一个问题,但如果你更喜欢这种方法,你只需要改变setStringListParameter使用Int而不是String:
小智 7
val ids = List(610113193610210035L, 220702198208189710L)
implicit object SetListLong extends SetParameter[List[Long]] {
def apply(vList: List[Long], pp: PositionedParameters) {
vList.foreach(pp.setLong)
}
}
val select = sql"""
select idnum from idnum_0
where idnum in ($ids#${",?" * (ids.size - 1)})
""".as[Long]
Run Code Online (Sandbox Code Playgroud)
@本·赖希是对的。这是另一个示例代码,在slick 3.1.0上进行测试。
($ids#${",?" * (ids.size - 1)})