¿Preguntas con declaraciones preparadas en Android?

En Android, android.database.sqlite.SQLiteStatement me permite usar declaraciones preparadas en SQLite para evitar ataques de inyección. Su método de execute es adecuado para crear / actualizar / eliminar operaciones, pero no parece haber ningún método para las consultas que devuelve un cursor o similar.

Ahora en iOS puedo crear declaraciones preparadas de tipo sqlite3_stmt* y usarlas para consultas, así que sé que esto no es una limitación de SQLite. ¿Cómo puedo realizar consultas con declaraciones preparadas en Android?

Una declaración preparada le permite hacer dos cosas

  • Acelerar el rendimiento ya que la base de datos no necesita analizar la sentencia cada vez
  • Bind & escape en la sentencia para que se salve contra ataques de inyección

No sé exactamente donde / cuando la implementación de SQLite de Androids realmente usa sqlite3_prepare (afiak no sqlite3_prepare_v2 – vea aquí ) pero lo usa de otra manera que no pudo obtener Alcanzó el tamaño MAX para errores de caché de compilación-sql .

Así que si quieres consultar la base de datos tienes que depender de la implementación no hay forma de saberlo para hacerlo con SQLiteStatement .

En cuanto a la seguridad de inyección, cada consulta de base de datos, insertar, etc método tiene versiones (a veces alternativas) que le permiten enlazar los argumentos.

Por ejemplo, si desea obtener un Cursor de

 SELECT * FROM table WHERE column1='value1' OR column2='value2' 

Cursor SQLiteDatabase#rawQuery(

  • String sql ,: SELECT completo que puede incluir ? en todos lados
  • String[] selectionArgs : lista de valores que reemplazan ? , Para que aparezcan

)

 Cursor c1 = db.rawQuery( "SELECT * FROM table WHERE column1=? OR column2=?", new String[] {"value1", "value2"} ); 

Cursor SQLiteDatabase#query (

  • String table nombre de tabla, puede incluir JOIN etc
  • String[] columns ,: lista de las columnas necesarias, null = *
  • String selection ,: WHERE cláusula withouth ¿ WHERE puede / debe incluir ?
  • String[] selectionArgs ,: lista de valores que reemplazan ? , Para que aparezcan
  • String groupBy Cláusula GROUP BY sin GROUP BY
  • String having : HAVING cláusula w / o HAVING
  • String orderBy : String orderBy ORDER BY sin ORDER BY

)

 Cursor c2 = db.query("table", null, "column1=? OR column2=?", new String[] {"value1", "value2"}, null, null, null); 

Vía ContentProviders – ese caso es ligeramente diferente ya que interactúa con un proveedor abstracto, no una base de datos. No hay ninguna garantía de que hay una base de datos sqlite que respalda el ContentProvider . Tan a menos que usted sepa qué columnas hay / cómo el abastecedor trabaja internamente usted debe pegarse a lo que la documentación dice.

Cursor ContentResolver#query(

  • Uri uri URI que representa la fuente de datos (traducido internamente a una tabla)
  • String[] projection lista de las columnas requeridas, null = *
  • String selection ,: WHERE cláusula withouth ¿ WHERE puede / debe incluir ?
  • String[] selectionArgs ,: lista de valores que reemplazan ? , Para que aparezcan
  • String sortOrder : String sortOrder ORDER BY sin ORDER BY

)

 Cursor c3 = getContentResolver().query( Uri.parse("content://provider/table"), null, "column=? OR column2=?", new String[] {"value1", "value2"}, null); 

Sugerencia: si desea LIMIT aquí, puede agregarlo a la cláusula ORDER BY :

 String sortOrder = "somecolumn LIMIT 5"; 

O dependiendo de la implementación del ContentProvider agrega como un parámetro al Uri :

 Uri.parse("content://provider/table?limit=5"); // or better via buildUpon() Uri audio = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; audio.buildUpon().appendQueryParameter("limit", "5"); 

En todos los casos ? Será reemplazado por la versión de escape de lo que se pone en el argumento de enlace.

? + "hack'me" = 'hack''me'

  • SQLiteException: Token no reconocido al leer de la base de datos
  • Simple exportación e importación de una base de datos SQLite en Android
  • Contexto de acceso en ContentProvider
  • Consulta de actualización de base de datos SQLite con múltiples condiciones de ubicación en Android
  • Android.database.CursorWindowAllocationException: La asignación de ventana de cursor de 2048 kb falló incluso después de cerrar el cursor
  • Rendimiento de procesamiento de datos recursivo utilizando Java y SQLite
  • Intent.ACTION_PICK devuelve el cursor vacío para algunos contactos
  • Sqlite excepción en crear sentencia de tabla
  • SQLite Android no puede abrir el archivo de base de datos
  • Android ContentProvider Esquema de URI para notificar a CursorAdapters escuchando consultas de OUTER JOIN
  • Estrategia de clave principal de Android (aplicación distribuida)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.