SQLite: getCount() or DatabaseUtils? - android

I am trying to test if a sqlite database is empty or not. I've read stackoverflow posts and many recommend using rawQuery and getCount() methods. Others recommend using DatabaseUtils.longForQuery and DatabaseUtils.queryNumEntries.
I am looking for speed since the number of rows in the database is large. I am looking for quick test to see if the number of rows is zero. If not, it is because there are 1 or more rows in the database. Would there be a method that aborts the count after 1 row is identified rather than counting all of the rows? If not, any thoughts on getCount vs. DatabaseUtils?

queryNumEntries as Google Doc where Added in API level 11
long count=0;
Cursor cursor = Database.DB.rawQuery("select count(*) from table;",null);
count=cursor.getLong(0);

The sql query SELECT COUNT(*) FROM table_name; runs pretty fast.
DatabaseUtils.queryNumEntries() uses this method. I would go with that.
You could run your own SQLiteDatabase.rawQuery() that does the above query. That should be good too.

Related

How to check number of rows in db before inserting

Scenario is like
Before inserting into sqlite db I have to check whether is it reached a particular number, say 10. I know it can be done by using 2 queries for get and insert.
Can it be done in 1 query in android and sqlite
INSERT INTO Customers (name, age)
SELECT 'MM', 20 WHERE (SELECT count(*) from Customers) < 10;
By use this query, we only insert new customer to database when total customers in database < 10
Considering the documentation for INSERT you can also insert a result of a select statement. So instead of inserting the values directly, you could assemble a select statement to only return your default values with coalesce if and only if a condition for the count yields true.
This is mostly an idea and theoretical approach, but worth trying.
To check how many rows in database, you need to make
select * from
query and get the cursor object. Cursor object have getCount method which return you size of cursor, its simply means to show all your records in table.
Cheers!!!

Possible to use ContentValues.put to update one column as sum of others

Is it possible to use ContentValues.put() to update a column in a SQLiteDatabse to be the sum of other columns?
I have searched on here and on the web and the closest answer I have found is: Update one column as sum of other two columns. This doesn't quite answer my question because it requires a raw database command, which I would prefer to avoid (if possible).
I have a fairly static database that I have generated unique permutations in (long setup, fast queries). I am attempting to set a total column at the end for even faster sorting on the permutations. I am currently attempting to use:
ContentValues values = new ContentValues();
values.put(totalVal, sumString);
where I have tried to set sumString to both:
=val_1+val_2+val_3...
and
val_1+val_2+val3...
When I look at my database in adb shell, sqlite3 I see:
Which looks... correct? Except when I query my database after this has been set, I get this in the log:
My val_* columns show values in the same adb shell, sqlite3 dump. Also, I do not set the totalVal column to this sumString until the val_* columns are all populated with their values.
Is it just not possible to use ContentValues.put()? Does it do some sort of internal escaping?
The reason it seems like it should work to me is the totalVal column is set to REAL so if ContentValues.put() does do internal escaping I thought I would get an error since I would essentially be putting a String value in a column that should only accept REAL.
Like I said earlier, my database is pretty static and only there for fast queries and sorting. It would be possible for me to loop through all the val_* columns and manually sum them up. Although, there are thousands of rows in my database so I was hoping to avoid this and was looking for a more elegant way to do this.
Thanks for the help.
SQLiteDatabase.update() is just a convenience method for updating rows in the database, so in your case you are just overcomplicating things trying to use ContentValues instead of SQLiteStatement and binding arguments which is what SQLiteDatabase.update() uses internally but preventing that column names were considered Strings.
It's not very clear from your example but if you are trying to update some values and at the same time calculate the totalVal do something like this
SQLiteStatement stmt = db.compileStatement("UPDATE mytable SET val_1=?, val_2=?, val_3=?, totalVal=val_1+val_2+val_3 WHERE expr");
stmt.bindLong(1, 1);
stmt.bindLong(2, 3);
stmt.bindLong(3, 5);
stmt.executeUpdateDelete();
EDIT
So as mentioned in your comment you don't need to bind values, it's even simpler
final int rows = db.compileStatement("UPDATE mytable SET totalVal=val_1+val_2+val_3").executeUpdateDelete();
and regarding your comment about "raw" SQL, ContentValues are not an option so this is the only way (AFAIK).

Create cursor from SQLiteStatement

I would like to use SQLiteStatement in my ContentProvider instead of the rawQuery or one of the other standard methods. I think using SQLiteStatement would give a more natural, native, efficient and less error prone approach to doing queries.
The problem is that I don't see a way to generate and return a Cursor. I realize I can use "call" and return a Bundle, but that approach requires that I cache and return all selected rows at the same time - this could be huge.
I will start looking at Android source code - I presume that "query" ultimately uses SQLiteStatement and somehow generates a Cursor. However, if anyone has any pointers or knowledge of this, I would greatly appreciate your sharing.
I would like to use SQLiteStatement in my ContentProvider instead of the rawQuery or one of the other standard methods. I think using SQLiteStatement would give a more natural, native, efficient and less error prone approach to doing queries.
Quoting the documentation for SQLiteStatement:
The statement cannot return multiple rows or columns, but single value (1 x 1) result sets are supported.
I fail to see why you would bother with a ContentProvider for single row, single column results, but, hey, it's your app...
The problem is that I don't see a way to generate and return a Cursor
Create a MatrixCursor and fill in the single result.

Performance problem with SimpleCursorAdapter in android

I'm trying to show a ListView filled with a SimpleCursorAdapter. The SimpleCursorAdapter receives a Cursor filled with the execution of a rawQuery like:
SELECT DISTINCT s.cod AS _id, s.name AS name FROM supplier s
INNER JOIN product p ON p.supplier = s.cod
INNER JOIN productprice pp ON pp.product = p.cod
WHERE
pp.category = 'w'
ORDER BY s.name
When I execute this query directly in the base, it returns 40 rows in less than 0.1 sec (normal). The execution of the rawQuery in the repository is very fast too. The problem is when I do the myListView.setAdapter(simpleCursorAdapter);. It takes more than 2 minutes! So i've changed the query to SELECT cod AS _id, name FROM supplier ORDER BY name and the execution of the setAdapter was pretty fast ("normal fast" hshs).
My questions:
Exist a limit of JOIN's that I can do in a rawQuery to fill a listView? Am I doing something wrong? Should I use query() in the repository instead of rawQuery()?
Sorry about the english and thanks in advance.
The Cursor you provide to the SimpleCursorAdapter is a resultset from the database query. If the database query is fast, then the problem is located in the CursorAdapter. I have experienced that CursorAdapters have poor performance (both using SimpleCursorAdapter and custom adapters extending CursorAdapter or ResourceAdapter). I ended up pulling the data from the Cursor, put in in an array, and extend the ArrayAdapter, which gave me much better performance.

How to return unique rows within a column in Android SQLite?

Really all I want to do is say the query SELECT DISTINCT column FROM table but I can't figure out how to structure it in the enourmous query methods that are part of SQLiteDatabase
I'm just trying to get the names of all contacts in a table.
You seem to know the sql query you want to run. Have you tried using rawQuery()?
You will probably find this version of the SQLiteDatabase#query method most useful.

Categories

Resources