How do I use prepared statements in SQlite in Android?
For prepared SQLite statements in Android there is SQLiteStatement. Prepared statements help you speed up performance (especially for statements that need to be executed multiple times) and also help avoid against injection attacks.
A prepared statement object is the compiled object code. All SQL must be converted into a prepared statement before it can be run. The life-cycle of a prepared statement object usually goes like this: Create the prepared statement object using sqlite3_prepare_v2().
We can retrieve anything from database using an object of the Cursor class. We will call a method of this class called rawQuery and it will return a resultset with the cursor pointing to the table. We can move the cursor forward and retrieve the data. This method return the total number of columns of the table.
A parameterized query is a type of SQL query that requires at least one parameter for execution. A placeholder is normally substituted for the parameter in the SQL query. The parameter is then passed to the query in a separate statement.
For prepared SQLite statements in Android there is SQLiteStatement. Prepared statements help you speed up performance (especially for statements that need to be executed multiple times) and also help avoid against injection attacks. See this article for a general discussion on prepared statements.
SQLiteStatement
is meant to be used with SQL statements that do not return multiple values. (That means you wouldn't use them for most queries.) Below are some examples:
String sql = "CREATE TABLE table_name (column_1 INTEGER PRIMARY KEY, column_2 TEXT)"; SQLiteStatement stmt = db.compileStatement(sql); stmt.execute();
The execute()
method does not return a value so it is appropriate to use with CREATE and DROP but not intended to be used with SELECT, INSERT, DELETE, and UPDATE because these return values. (But see this question.)
String sql = "INSERT INTO table_name (column_1, column_2) VALUES (57, 'hello')"; SQLiteStatement statement = db.compileStatement(sql); long rowId = statement.executeInsert();
Note that the executeInsert()
method is used rather than execute()
. Of course, you wouldn't want to always enter the same things in every row. For that you can use 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); // 1-based: matches first '?' in sql string statement.bindString(2, stringValue); // matches second '?' in sql string long rowId = statement.executeInsert();
Usually you use prepared statements when you want to quickly repeat something (like an INSERT) many times. The prepared statement makes it so that the SQL statement doesn't have to be parsed and compiled every time. You can speed things up even more by using transactions. This allows all the changes to be applied at once. Here is an example:
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(); }
Check out these links for some more good info on transactions and speeding up database inserts.
This is a basic example. You can also apply the concepts from the section above.
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();
The executeUpdateDelete()
method can also be used for DELETE statements and was introduced in API 11. See this Q&A.
Here is an example.
try { db.beginTransaction(); String sql = "DELETE FROM " + table_name + " WHERE " + column_1 + " = ?"; SQLiteStatement statement = db.compileStatement(sql); for (Long id : words) { statement.clearBindings(); statement.bindLong(1, id); statement.executeUpdateDelete(); } db.setTransactionSuccessful(); } catch (SQLException e) { Log.w("Exception:", e); } finally { db.endTransaction(); }
Normally when you run a query, you want to get a cursor back with lots of rows. That's not what SQLiteStatement
is for, though. You don't run a query with it unless you only need a simple result, like the number of rows in the database, which you can do with simpleQueryForLong()
String sql = "SELECT COUNT(*) FROM table_name"; SQLiteStatement statement = db.compileStatement(sql); long result = statement.simpleQueryForLong();
Usually you will run the query()
method of SQLiteDatabase to get a 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);
See this answer for better details about queries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With