Saya mencoba melakukan kueri SQL berikut di 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});
Namun, Android tidak mengganti tanda tanya dengan nilai yang benar. Saya dapat melakukan hal berikut, namun, ini tidak melindungi dari injeksi SQL:
String query = "SELECT * FROM table WHERE name IN (" + names + ")";
Cursor cursor = mDb.rawQuery(query, null);
Bagaimana cara mengatasi masalah ini dan dapat menggunakan klausa IN?
makePlaceholders
bisa diganti denganTextUtils.join(",", Collections.nCopies(len, "?"))
. Lebih sedikit bertele-tele.Caused by: android.database.sqlite.SQLiteException: near ",": syntax error (code 1): , while compiling: SELECT url FROM tasks WHERE url=?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
Contoh singkat, berdasarkan jawaban pengguna166390:
sumber
Sayangnya tidak ada cara untuk melakukan itu (jelas
'name1', 'name2'
bukan nilai tunggal dan karena itu tidak dapat digunakan dalam pernyataan yang disiapkan).Jadi, Anda harus menurunkan pandangan Anda (misalnya dengan membuat kueri yang sangat spesifik, tidak dapat digunakan kembali seperti
WHERE name IN (?, ?, ?)
) atau tidak menggunakan prosedur tersimpan dan mencoba mencegah injeksi SQL dengan beberapa teknik lain ...sumber
Seperti yang disarankan dalam jawaban yang diterima tetapi tanpa menggunakan fungsi kustom untuk menghasilkan '?' Yang dipisahkan koma. Silakan periksa kode di bawah ini.
sumber
Anda dapat menggunakan
TextUtils.join(",", parameters)
untuk memanfaatkan parameter pengikatan sqlite, di manaparameters
daftar dengan"?"
placeholder dan string hasil seperti itu"?,?,..,?"
.Ini adalah contoh kecilnya:
sumber
Sebenarnya Anda bisa menggunakan cara asli android untuk membuat kueri sebagai ganti rawQuery:
sumber
Ini tidak valid
Ini Valid
Menggunakan ContentResolver
sumber
Di Kotlin, Anda dapat menggunakan joinToString
sumber
Saya menggunakan
Stream
API untuk ini:sumber