Join FlipAndroid.COM Telegram Group: https://t.me/joinchat/F_aqThGkhwcLzmI49vKAiw


¿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?

  • Excepción de SQLite "no such table" de Android
  • Rellene ExpandableListView con datos de SQLite
  • Cómo guardar imágenes en la base de datos
  • Android classificar los resultados de la consulta sqlite ignorando el caso
  • Longitud máxima de Android Sqlite String?
  • Java - java.lang.IllegalStateException: No se pudo leer la fila 0, col -1 de CursorWindow
  • Exportar la base de datos SQLite al archivo csv en android
  • Base de datos de SQLite de SQL, bloqueo y versión
  • One Solution collect form web for “¿Preguntas 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'

    FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.