Eine Zeichenfolge des Formulars "?, ?, ..., ?"
kann eine dynamisch erstellte Zeichenfolge sein und sicher in die ursprüngliche SQL-Abfrage eingefügt werden (da es sich um ein eingeschränktes Formular handelt, das keine externen Daten enthält). Anschließend können die Platzhalter wie gewohnt verwendet werden.
Stellen Sie sich eine Funktion vor, String makePlaceholders(int len)
die len
durch Kommas getrennte Fragezeichen zurückgibt. Dann:
String[] names = { "name1", "name2" }; // do whatever is needed first
String query = "SELECT * FROM table"
+ " WHERE name IN (" + makePlaceholders(names.length) + ")";
Cursor cursor = mDb.rawQuery(query, names);
Stellen Sie einfach sicher, dass Sie genau so viele Werte wie Orte übergeben. Die standardmäßige maximale Anzahl von Hostparametern in SQLite beträgt 999 - zumindest in einem normalen Build, bei Android nicht sicher :)
Viel Spaß beim Codieren.
Hier ist eine Implementierung:
String makePlaceholders(int len) {
if (len < 1) {
// It will lead to an invalid query anyway ..
throw new RuntimeException("No placeholders");
} else {
StringBuilder sb = new StringBuilder(len * 2 - 1);
sb.append("?");
for (int i = 1; i < len; i++) {
sb.append(",?");
}
return sb.toString();
}
}
makePlaceholders
könnte durch ersetzt werdenTextUtils.join(",", Collections.nCopies(len, "?"))
. Weniger ausführlich.Caused by: android.database.sqlite.SQLiteException: near ",": syntax error (code 1): , while compiling: SELECT url FROM tasks WHERE url=?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
Kurzes Beispiel, basierend auf der Antwort von user166390:
quelle
Leider gibt es keine Möglichkeit, dies zu tun (offensichtlich
'name1', 'name2'
ist es kein einzelner Wert und kann daher nicht in einer vorbereiteten Aussage verwendet werden).Sie müssen also Ihre Sicht verringern (z. B. indem Sie sehr spezifische, nicht wiederverwendbare Abfragen erstellen
WHERE name IN (?, ?, ?)
) oder keine gespeicherten Prozeduren verwenden und versuchen, SQL-Injektionen mit einigen anderen Techniken zu verhindern ...quelle
Wie in der akzeptierten Antwort vorgeschlagen, jedoch ohne Verwendung einer benutzerdefinierten Funktion zum Generieren eines durch Kommas getrennten '?'. Bitte überprüfen Sie den Code unten.
quelle
Sie können
TextUtils.join(",", parameters)
SQLite-Bindungsparameter nutzen, wobeiparameters
eine Liste mit"?"
Platzhaltern und die Ergebniszeichenfolge so etwas wie ist"?,?,..,?"
.Hier ist ein kleines Beispiel:
quelle
Tatsächlich könnten Sie anstelle von rawQuery die native Abfragemethode von Android verwenden:
quelle
Dies ist nicht gültig
Dies ist gültig
Verwenden von ContentResolver
quelle
In Kotlin können Sie joinToString verwenden
quelle
Ich benutze die
Stream
API dafür:quelle