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


¿Cuál es la forma correcta de hacer inserciones / actualizaciones / eliminaciones en Android SQLiteDatabase utilizando una cadena de consulta?

He estado buscando en la documentación oficial ( http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html ) y la referencia cruzada con StackOverflow mensajes y el comportamiento observado real, y la documentación parece ser Engañosa y posiblemente equivocada en varios aspectos.

Estoy tratando de realizar consultas parametrizadas para insertar / actualizar / eliminar, como se puede hacer para seleccionar con rawQuery(String sql, String[] arguments). Necesito hacerlo a través de una consulta en lugar de usar los métodos insert / update / delete en la clase SQLiteDatabase porque en muchos casos las consultas abarcan varias tablas y en cualquier caso hemos escrito un gran conjunto de consultas que usamos para esta aplicación A través de todas nuestras plataformas (también escrito para SQLite), y sería altamente preferible usarlo como-es.

Esto es lo que encuentro confuso / engañoso:

  • El doc dice para rawQuery que las declaraciones no deben ser terminadas por un punto y coma, pero en realidad no parece hacer ninguna diferencia. Esto me importa porque tenemos un enorme documento XML lleno de consultas que utilizo en mi aplicación en varias plataformas y prefiero mantenerlo idéntico si es posible.

  • rawQuery no parece funcionar para los insertos (sí, he intentado con y sin el punto y coma). El doctor no dice nada sobre esto. Veo que devuelve un Cursor, que supongo podría ser una indicación oblicua de que sólo funciona con una selección, pero no necesariamente – podría simplemente devolver un Cursor de cero longitud o nulo cuando no era conjunto de resultados.

  • execSQL(String sql, Object[] bindArgs) dice explícitamente que no funciona con insertos, pero de hecho lo hace!

  • Además, aunque execSQL(String, Object[]) específicamente le dice que no intente operaciones CRUD, su versión sin parámetros no contiene tal advertencia, y también funciona bien para ese propósito (con la desventaja de no permitir parámetros de SQL).

El resultado de todo esto es que la única manera que puedo encontrar para ejecutar con éxito inserciones con argumentos parametrizados es usar el método de trabajo que los documentos le indican explícitamente que no utilice para ese propósito.

Además, es realmente una lástima que rawQuery no funcionará para inserts / updates / deletes, porque tenemos una capa de datos generalizada y sería más elegante si pudiéramos usar una sola llamada de API unificada para ejecutar todas nuestras consultas CRUD en el base de datos.

Entonces, ¿qué está pasando aquí? ¿Esta documentación está irremediablemente desactualizada? ¿Está bien usar execSql para hacer inserciones, actualizaciones, etc.? ¿Alguien ha logrado hacer inserciones con rawQuery?


Apéndice:

Ejecución contra sistema operativo: Android 4.3.

Ejemplos de consultas (lo que funciona, lo que no funciona)

 // Works db.execSql("INSERT into MyTable (Col1, Col2) VALUES (?, ?)", new String[] { "Foo", "Bar" }); db.execSql("INSERT into MyTable (Col1, Col2) VALUES (?, ?);", new String[] { "Foo", "Bar" }); // No exception thrown, but no changes made to the database db.rawQuery("INSERT into MyTable (Col1, Col2) VALUES (?, ?)", new String[] { "Foo", "Bar" }); db.rawQuery("INSERT into MyTable (Col1, Col2) VALUES (?, ?);", new String[] { "Foo", "Bar" }); 

2 Solutions collect form web for “¿Cuál es la forma correcta de hacer inserciones / actualizaciones / eliminaciones en Android SQLiteDatabase utilizando una cadena de consulta?”

Tienes razón. La documentación es confusa. En general, el diseño intenta proporcionar un conveniente Java wrapper alrededor de la API C sqlite3. Para la mayoría de las veces funciona bien si se utiliza de la manera que los diseñadores pretenden, por ejemplo, utilizando los métodos de conveniencia para operaciones CRUD. Pero también necesitaban proporcionar métodos de consulta en bruto execSQL() y rawQuery() para casos en los que los métodos CRUD de conveniencia no rawQuery() suficientemente potentes o no rawQuery() aplicables en absoluto ( CREATE TABLE etc.). Esto causa abstracciones con fugas.

El doc dice para rawQuery que las declaraciones no deben ser terminadas por un punto y coma, pero en realidad no parece hacer ninguna diferencia. Esto me importa porque tenemos un enorme documento XML lleno de consultas que utilizo en mi aplicación en varias plataformas y prefiero mantenerlo idéntico si es posible.

Los documentos son malos. De hecho, Android SQLiteDatabase llama a rawQuery con una cadena de consulta terminada en punto y coma .

rawQuery no parece funcionar para los insertos (sí, he intentado con y sin el punto y coma). El doctor no dice nada sobre esto. Veo que devuelve un Cursor, que supongo podría ser una indicación oblicua de que sólo funciona con una selección, pero no necesariamente – podría simplemente devolver un Cursor de cero longitud o nulo cuando no era conjunto de resultados.

No funciona, pero usted tendrá que entender cómo funciona en el nivel nativo.

Piense en execSQL() como sqlite3_exec() que ejecuta la consulta y devuelve el éxito o un código de error.

Piense en rawQuery() como sqlite3_prepare() que compila la consulta pero no la ejecuta todavía. Para ejecutarlo, utilice uno de los moveTo...() en el Cursor . Piense en esto como sqlite3_step() . La combinación de cualquier rawQuery() con moveTo...() realmente alterará la base de datos.

execSQL(String sql, Object[] bindArgs) dice explícitamente que no funciona con select, pero de hecho lo hace!

Además, aunque execSQL(String, Object[]) específicamente le dice que no intente operaciones CRUD, su versión sin parámetros no contiene tal advertencia, y también funciona bien para ese propósito (con la desventaja de no permitir parámetros de SQL).

Funciona bien para todas las operaciones CRUD. Para la parte de lectura R de CRUD, simplemente no hay forma de obtener los datos seleccionados.

Lo que quieres es execSQL () para inserciones. O puede hacerlo de esta manera:

 ContentValues values = new ContentValues(); values.put ("col1", "foo"); values.put ("cols2", "bar"); getDb().insertOrThrow ("MyTable", null, values); 

Para consultas, puede utilizar rawQuery.

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