¿Cómo uso declaraciones preparadas en SQlite en Android?¿Cómo uso declaraciones preparadas en SQlite en Android?
Respuesta
utilizo declaraciones preparadas en Android todo el tiempo, es bastante simple:
SQLiteDatabase db = dbHelper.getWritableDatabase();
SQLiteStatement stmt = db.compileStatement("SELECT * FROM Country WHERE code = ?");
stmt.bindString(1, "US");
stmt.execute();
¿Es posible con declaraciones preparadas poner argumentos que no son valores? como "SELECT * FROM?"? – Pablo
No sé cómo esta respuesta puede tener tantos votos. SQLIteStatement # execute no se debe usar para consultas Sql, solo declaraciones. Por favor, consulte http://developer.android.com/reference/android/database/sqlite/SQLiteStatement.html#execute() – simao
Sí, ese es un mal ejemplo que di, no funcionará para consultas como declaraciones SELECT ... – jasonhudgins
jasonhudgins ejemplo no funcionará. No se puede ejecutar una consulta con stmt.execute()
y obtener un valor (o un Cursor
) de nuevo.
Solo puede precompilar sentencias que no devuelven ninguna fila (como una inserción o una declaración de tabla) o una sola fila y columna (y use simpleQueryForLong()
o simpleQueryForString()
).
Si quieres un cursor en cambio, entonces usted podría considerar algo como esto:
SQLiteDatabase db = dbHelper.getWritableDatabase();
public Cursor fetchByCountryCode(String strCountryCode)
{
/**
* SELECT * FROM Country
* WHERE code = US
*/
return cursor = db.query(true,
"Country", /**< Table name. */
null, /**< All the fields that you want the
cursor to contain; null means all.*/
"code=?", /**< WHERE statement without the WHERE clause. */
new String[] { strCountryCode }, /**< Selection arguments. */
null, null, null, null);
}
/** Fill a cursor with the results. */
Cursor c = fetchByCountryCode("US");
/** Retrieve data from the fields. */
String strCountryCode = c.getString(cursor.getColumnIndex("code"));
/** Assuming that you have a field/column with the name "country_name" */
String strCountryName = c.getString(cursor.getColumnIndex("country_name"));
ver este fragmento Genscripts en caso de que quiera una más completa. Tenga en cuenta que esta es una consulta SQL parametrizada, por lo que, en esencia, es una declaración preparada.
Pequeño error en el código anterior: debe ser "new String [] {strCountryCode}, "en lugar de" new String {strCountryCode} ". –
Necesita mover el cursor antes de recuperar los datos – Chin
Para obtener un cursor, no se puede utilizar un compiledStatement. Sin embargo, si desea utilizar una declaración SQL completamente preparada, recomiendo una adaptación del método de jbaez ... Usando db.rawQuery()
en lugar de db.query()
.
En cuanto a datos SQLite preparados en Android hay SQLiteStatement. declaraciones preparadas le ayudan a acelerar el rendimiento (especialmente para los estados que necesitan ser ejecutados varias veces) y también ayudar a evitar los ataques de inyección. Ver this article para una discusión general sobre declaraciones preparadas.
SQLiteStatement
está destinado a utilizarse con sentencias SQL que no devuelven valores múltiples. (Esto significa que no los utilizaría para la mayoría de las consultas.) A continuación se presentan algunos ejemplos:
Create a table
String sql = "CREATE TABLE table_name (column_1 INTEGER PRIMARY KEY, column_2 TEXT)";
SQLiteStatement stmt = db.compileStatement(sql);
stmt.execute();
El método execute()
no devuelve un valor por lo que es apropiado utilizar con CREATE y DROP pero no está destinado a usarse con SELECT, INSERT, DELETE y UPDATE porque estos valores de retorno. (Pero vea this question.)
Insert values
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (57, 'hello')";
SQLiteStatement statement = db.compileStatement(sql);
long rowId = statement.executeInsert();
Tenga en cuenta que el método executeInsert()
se utiliza en lugar de execute()
. Por supuesto, no querrá siempre ingresar las mismas cosas en cada fila. Para eso puedes usar bindings.
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (?, ?)";
SQLiteStatement statement = db.compileStatement(sql);
int intValue = 57;
String stringValue = "hello";
statement.bindLong(1, intValue); // These match to the two question marks in the sql string
statement.bindString(2, stringValue);
long rowId = statement.executeInsert();
Por lo general, usted utiliza declaraciones preparadas cuando desea repetir rápidamente algo (como un INSERT) muchas veces. La sentencia preparada hace que la sentencia SQL no tenga que ser analizada y compilada cada vez. Puede acelerar aún más las cosas usando transactions. Esto permite que todos los cambios se apliquen a la vez. Aquí está un ejemplo:
String stringValue = "hello";
try {
db.beginTransaction();
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (?, ?)";
SQLiteStatement statement = db.compileStatement(sql);
for (int i = 0; i < 1000; i++) {
statement.clearBindings();
statement.bindLong(1, i);
statement.bindString(2, stringValue + i);
statement.executeInsert();
}
db.setTransactionSuccessful(); // This commits the transaction if there were no exceptions
} catch (Exception e) {
Log.w("Exception:", e);
} finally {
db.endTransaction();
}
visita estos links para un poco más de buena información sobre las transacciones y la aceleración de las inserciones de bases de datos.
- Atomic Commit In SQLite (Great en explicación profundidad, pase a la Parte 3)
- Database transactions
- Android SQLite bulk insert and update example
- Android SQLite Transaction Example with INSERT Prepared Statement
- Turbocharge your SQLite inserts on Android
- https://stackoverflow.com/a/8163179/3681880
Update rows
Este es un ejemplo básico. También puede aplicar los conceptos de la sección anterior.
String sql = "UPDATE table_name SET column_2=? WHERE column_1=?";
SQLiteStatement statement = db.compileStatement(sql);
int id = 7;
String stringValue = "hi there";
statement.bindString(1, stringValue);
statement.bindLong(2, id);
int numberOfRowsAffected = statement.executeUpdateDelete();
Nota: executeUpdateDelete()
también se puede utilizar para los estados eliminar y se introdujo en la API 11. See this Q&A.
Query
Normalmente, cuando se ejecuta una consulta, que desea obtener un cursor de nuevo con una gran cantidad de filas. Sin embargo, eso no es lo que SQLiteStatement
es. No ejecuta una consulta con él a menos que sólo necesita un simple resultado, al igual que el número de filas en la base de datos, lo que se puede hacer con simpleQueryForLong()
String sql = "SELECT COUNT(*) FROM table_name";
SQLiteStatement statement = db.compileStatement(sql);
long result = statement.simpleQueryForLong();
Por lo general, que se ejecutará el método de SQLiteDatabasequery()
para obtener un cursor
SQLiteDatabase db = dbHelper.getReadableDatabase();
String table = "table_name";
String[] columnsToReturn = { "column_1", "column_2" };
String selection = "column_1 =?";
String[] selectionArgs = { someValue }; // matched to "?" in selection
Cursor dbCursor = db.query(table, columnsToReturn, selection, selectionArgs, null, null, null);
Ver this answer para más detalles acerca de las consultas.
Solo un recordatorio: los métodos .bindString/.bindLong/... están basados en 1. –
¡Respuesta asombrosa! gracias @Suragch –
Estaba mirando debajo de los métodos de conveniencia de Android como .query, .insert y .delete y noté que usan SQLiteStatement bajo el capó. ¿No sería más fácil simplemente usar métodos de conveniencia en lugar de construir sus propias declaraciones? –
- 1. declaraciones preparadas sqlite - cómo depurar
- 2. Consultas con declaraciones preparadas en Android?
- 3. En SQLite, ¿las declaraciones preparadas realmente mejoran el rendimiento?
- 4. Recursividad en declaraciones preparadas
- 5. Declaraciones preparadas en VB.NET
- 6. ¿Cómo uso las declaraciones preparadas para insertar registros MÚLTIPLES en SQlite usando Python/Django?
- 7. Uso de declaraciones preparadas con JDBCTemplate
- 8. Cierre de declaraciones preparadas
- 9. ¿Cómo funcionan las declaraciones preparadas?
- 10. ¿Hay inconvenientes en el uso de declaraciones preparadas?
- 11. mysql declaraciones preparadas permanentemente
- 12. Declaraciones preparadas de PHP PDO
- 13. ¿Cuándo * no * usar declaraciones preparadas?
- 14. ¿Inyecciones SQL con declaraciones preparadas?
- 15. Declaraciones preparadas MySQLi error reporting
- 16. Declaraciones preparadas y controladores JDBC
- 17. ¿Cómo se utiliza en las cláusulas con mysqli declaraciones preparadas
- 18. Declaraciones preparadas junto con Connection Pooling
- 19. Declaraciones y transacciones preparadas de MySQL
- 20. Uso de SQLite desde libGDX en Android
- 21. Spring NamedParameterJDBCTemplate reutilización de las declaraciones preparadas
- 22. PDO, Mysql y declaraciones preparadas nativas
- 23. declaraciones preparadas de mysqli y mysqli_real_escape_string
- 24. Declaraciones preparadas MySQLi con el operador IN
- 25. Son declaraciones preparadas compatibles con MySQL incorporado
- 26. ¿Es necesario mysql_real_escape_string() al usar declaraciones preparadas?
- 27. ¿Las declaraciones preparadas ralentizan notablemente el programa?
- 28. Nombres de columnas variables usando declaraciones preparadas
- 29. ¿Qué tokens se pueden parametrizar en declaraciones preparadas con PDO?
- 30. Poniendo tiempos de espera en las declaraciones preparadas
Considere cambiar la respuesta aceptada. – Suragch
estuvo de acuerdo - considere cambiar la respuesta ... la mentalidad de rebaño subió la respuesta aceptada, cuando existe una solución mejor. – LamonteCristo
Pablo, por favor, cambie la respuesta aceptada ... el ejemplo dado ni siquiera se ejecuta. Y nuestros downvotes no son suficientes para destrabarlo. – SparK