difference between rawquery and execSQL in android sqlite database
What is the exact difference between using rawquery and execSQL ?? While writing a query in android activity, when to use rawquery and when to use execSQL ?
Solution 1:
From API documentation:
void execSQL (String sql)
Execute a single SQL statement that is NOT a SELECT or any other SQL statement that returns data.
void execSQL (String sql, Object[] bindArgs)
Execute a single SQL statement that is NOT a SELECT/INSERT/UPDATE/DELETE.
The documentation is inconsistent but they behave both the same. Documentation of the latter is more in depth.
Cursor rawQuery (String sql, String[] selectionArgs)
Runs the provided SQL and returns a Cursor over the result set.
Uses for rawQuery
are:
- You want to query the database with a
SELECT
statement.
=>rawQuery("SELECT ...
returns a set of rows and columns in aCursor
.- It's more efficient to use
DatabaseUtils.longForQuery(SQLiteDatabase, String, String[])
orDatabaseUtils.stringForQuery(...)
in cases there is only a 1x1 query result, like fromSELECT count(*) FROM table
(which also has it's own dedicated method:DatabaseUtils.queryNumEntries(...)
) - this skips creation of aCursor
object & simplifies code since there is also nothing to close, moveToNext, etc.
- It's more efficient to use
- Special cases like
PRAGMA table_info
that returns data in rows (see this question) - Note: Do not use
rawQuery
forINSERT
,UPDATE
orDELETE
or anything else that modifies the database. You'll run into "Why does a delete rawQuery need a moveToFirst in order to actually delete the rows?". Reason being that queries can defer reading the result until needed (= access to the cursor) which means for SQLite delaying execution of the statement.
Uses for execSQL
are:
- You have "instructions" for the database. Like
CREATE TABLE
(or any otherCREATE
statement, e.g.CREATE INDEX
),DROP
,PRAGMA
s that set properties rather than returning them, ... -
INSERT
,UPDATE
orDELETE
when you're not interested in the amount of rows modified or the row id of the last insert.- When you need those, either use the
update()
,insert()
,delete()
methods or use a second statement to read those:DatabaseUtils.longForQuery
with eitherSELECT last_insert_rowid()
orSELECT changes()
. Both return only 1 integer value. (see "Get updated rows count from SQLite in Android using a raw query?" and “SELECT last_insert_rowid()” returns always “0”)
- When you need those, either use the
- Anything else that relies on executing a statement.
Solution 2:
if you want to execute something in database without concerning its output (e.g create/alter tables), then use execSQL, but if you are expecting some results in return against your query (e.g. select records) then use rawQuery