J'essaie de faire la requête SQL suivante dans Android:
String names = "'name1', 'name2"; // in the code this is dynamically generated
String query = "SELECT * FROM table WHERE name IN (?)";
Cursor cursor = mDb.rawQuery(query, new String[]{names});
Cependant, Android ne remplace pas le point d'interrogation par les valeurs correctes. Je pourrais faire ce qui suit, cependant, cela ne protège pas contre l'injection SQL:
String query = "SELECT * FROM table WHERE name IN (" + names + ")";
Cursor cursor = mDb.rawQuery(query, null);
Comment contourner ce problème et pouvoir utiliser la clause IN?
makePlaceholders
pourrait être remplacé parTextUtils.join(",", Collections.nCopies(len, "?"))
. Moins verbeux.Caused by: android.database.sqlite.SQLiteException: near ",": syntax error (code 1): , while compiling: SELECT url FROM tasks WHERE url=?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
Exemple court, basé sur la réponse de l'utilisateur166390:
la source
Malheureusement, il n'y a aucun moyen de le faire (il ne
'name1', 'name2'
s'agit évidemment pas d'une valeur unique et ne peut donc pas être utilisée dans une instruction préparée).Vous devrez donc baisser vos vues (par exemple en créant des requêtes très spécifiques, non réutilisables comme
WHERE name IN (?, ?, ?)
) ou ne pas utiliser de procédures stockées et essayer d'empêcher les injections SQL avec d'autres techniques ...la source
Comme suggéré dans la réponse acceptée, mais sans utiliser la fonction personnalisée pour générer un «?» Séparé par des virgules. Veuillez vérifier le code ci-dessous.
la source
Vous pouvez utiliser
TextUtils.join(",", parameters)
pour tirer parti des paramètres de liaison sqlite, où separameters
trouve une liste avec des"?"
espaces réservés et la chaîne de résultat est quelque chose comme"?,?,..,?"
.Voici un petit exemple:
la source
En fait, vous pouvez utiliser la méthode native de requête d'Android au lieu de rawQuery:
la source
Ce n'est pas valide
Ceci est valide
Utilisation de ContentResolver
la source
Dans Kotlin, vous pouvez utiliser joinToString
la source
J'utilise l'
Stream
API pour cela:la source