Я пытаюсь выполнить следующий SQL-запрос в 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});
Однако Android не заменяет вопросительный знак правильными значениями. Я мог бы сделать следующее, однако это не защищает от SQL-инъекции:
String query = "SELECT * FROM table WHERE name IN (" + names + ")";
Cursor cursor = mDb.rawQuery(query, null);
Как я могу обойти эту проблему и использовать предложение IN?
makePlaceholders
можно заменить наTextUtils.join(",", Collections.nCopies(len, "?"))
. Менее подробный.Caused by: android.database.sqlite.SQLiteException: near ",": syntax error (code 1): , while compiling: SELECT url FROM tasks WHERE url=?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
Краткий пример, основанный на ответе пользователя 166390:
источник
К сожалению, нет способа сделать это (очевидно, что
'name1', 'name2'
это не одно значение и поэтому не может использоваться в подготовленном операторе).Таким образом, вам придется снизить внимание (например, создавая очень конкретные, не подлежащие повторному использованию запросы, например
WHERE name IN (?, ?, ?)
) или не использовать хранимые процедуры и попытаться предотвратить инъекции SQL с помощью некоторых других методов ...источник
Как предлагается в принятом ответе, но без использования настраиваемой функции для генерации разделенных запятыми '?'. Пожалуйста, проверьте код ниже.
источник
Вы можете использовать,
TextUtils.join(",", parameters)
чтобы воспользоваться параметрами привязки sqlite, гдеparameters
это список с"?"
заполнителями, а строка результата выглядит примерно так"?,?,..,?"
.Вот небольшой пример:
источник
На самом деле вы можете использовать собственный способ запросов Android вместо rawQuery:
источник
Это не действует
Это действительно
Использование ContentResolver
источник
В Kotlin вы можете использовать joinToString
источник
Я использую
Stream
для этого API:источник