sql
prefiks odblokowuje StringContext
gdzie można ustawić parametry SQL. Nie ma parametru SQL dla listy, więc możesz łatwo zakończyć otwarcie się na SQL injection tutaj, jeśli nie jesteś ostrożny. Jest kilka dobrych (i trochę niebezpiecznych) sugestii dotyczących radzenia sobie z tym problemem z SQLServer na this question. Masz kilka opcji:
Najprościej jest prawdopodobnie użyć operatora #$
wraz z mkString
interpolować dynamicznego SQL:
val sql = sql"""SELECT * FROM coffee WHERE id IN (#${ids.mkString(",")})"""
nie poprawnie używać parametrów, a zatem może być otwarty do SQL- wstrzyknięcie i inne problemy.
Inną opcją jest użycie regularny ciąg interpolacji i mkString
zbudować oświadczenie:
val query = s"""SELECT * FROM coffee WHERE id IN (${ids.mkString(",")})"""
StaticQuery.queryNA[Coffee](query)
To jest zasadniczo takie samo podejście, jak przy użyciu #$
, ale może być bardziej elastyczny w przypadku ogólnym.
Jeśli luka SQL-injection jest poważnym problemem (np. Jeśli elementy ids
są dostarczane przez użytkownika), można zbudować zapytanie z parametrem dla każdego elementu z ids
. Następnie trzeba zapewnić wystąpienie zwyczaj SetParameter
tak śliskie, że może obrócić List
do parametrów:
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)
Ponieważ Twój ids
są Ints
, to chyba mniejszy problem, ale jeśli wolisz tej metody, po prostu trzeba zmienić setStringListParameter
używać Int
zamiast String
:
Jeśli 'ids' ma typ' List [Int] 'Nie widzę jak wtrysk sql jest możliwy, nawet jeśli są dostarczane przez użytkownika. – Daenyth
@Daenyth Jest to zdecydowanie mniejszy problem (chociaż czasami całkowite wstrzyknięcie SQL może być problemem, ponieważ powoduje podzielenie przez zero lub inne wyjątki, a następnie wykorzystanie stanu błędu - Google "liczby całkowite wtrysku sql"). Ale uważam, że najlepiej jest używać parametrów, aby uniknąć problemów na drodze (np. Co jeśli inny programista zmienił typ na "Ciąg" w dół, aby uwzględnić nowe typy identyfikatorów, które zawierają niektóre znaki). Naprawdę właśnie zakryłem sprawę, gdy jest tu "String". –
Dzięki za odpowiedź Ben! Bardzo pouczające o rozwiązaniach z możliwymi słabymi punktami. Zgadzam się jednak z @Denyth, że nie można sql wstrzykiwać z jawnym typem całkowitym. –