问题
I am trying to return a list of results using Anorm using a query that returns matching rows for a set of ids. Eg.
select *
from example
where id in (1,2,3,4,5)
If I try
SQL(
"""
select *
from example
where id in ({ids})
"""
).on('ids -> ids).as(int("id") ~ str("name") *)
where ids is the String "1,2,3,4,5" it will only return the first row. What is the correct way to inject the set of ids?
回答1:
There's no simple way of doing it AFAIK.
This is how I solved it:
def findSomething(ids: String) = {
// Split up the comma separated values
val sids = ids split ","
// Create a list of keys (id0, id1, id2, ...)
val keys = for ( i <- 0 until sids.size ) yield ("id" + i)
// Create a seq of parameterized values
val values = sids map (toParameterValue(_))
// Now zip together the keys and values into list of tuples
val params = keys zip values
DB.withConnection { implicit connection =>
SQL(
"""
select *
from example
where id in ({%s})
""".format(keys.mkString("},{"))
).on(
params: _*
).as(
int("id") ~ str("name") *
)
}
}
NB
The cruical part here is the string formatting in the SQL statement. It is vulnerable for SQL injection if you don't have total control of your input parameters.
来源:https://stackoverflow.com/questions/15864564/play-framework-2-0-correct-way-to-represent-a-set-in-a-query-using-anorm