Estou tentando fazer a seguinte consulta SQL no 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});
No entanto, o Android não substitui o ponto de interrogação pelos valores corretos. Eu poderia fazer o seguinte, no entanto, isso não protege contra injeção de SQL:
String query = "SELECT * FROM table WHERE name IN (" + names + ")";
Cursor cursor = mDb.rawQuery(query, null);
Como posso contornar esse problema e ser capaz de usar a cláusula IN?
makePlaceholders
poderia ser substituído porTextUtils.join(",", Collections.nCopies(len, "?"))
. Menos prolixo.Caused by: android.database.sqlite.SQLiteException: near ",": syntax error (code 1): , while compiling: SELECT url FROM tasks WHERE url=?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?
Pequeno exemplo, com base na resposta do usuário166390:
fonte
Infelizmente, não há como fazer isso (obviamente
'name1', 'name2'
não é um valor único e, portanto, não pode ser usado em uma instrução preparada).Portanto, você terá que diminuir sua mira (por exemplo, criando consultas muito específicas e não reutilizáveis, como
WHERE name IN (?, ?, ?)
) ou não usar procedimentos armazenados e tentar evitar injeções de SQL com algumas outras técnicas ...fonte
Como sugerido na resposta aceita, mas sem usar a função personalizada para gerar '?' Separado por vírgula. Por favor, verifique o código abaixo.
fonte
Você pode usar
TextUtils.join(",", parameters)
para tirar proveito dos parâmetros de vinculação do sqlite, ondeparameters
é uma lista com"?"
espaços reservados e a string de resultado é algo como"?,?,..,?"
.Aqui está um pequeno exemplo:
fonte
Na verdade, você pode usar a forma nativa de consultar do Android em vez de rawQuery:
fonte
Isto não é válido
Isto é válido
Usando ContentResolver
fonte
Em Kotlin, você pode usar joinToString
fonte
Eu uso a
Stream
API para isso:fonte