Count SQLite Android how to display cursor properly - android

I have a simple function with SQLite raw query, it looks like :
public Cursor getOccurations ()
{
SQLiteDatabase db =this.getWritableDatabase();
Cursor data= db.rawQuery("select count(*) from Beacon_occurations where BEACON_ADDRESS='" + COL_2 + "' and TIME='" + COL_3 +"'", null);
return data;
}
And now here is a question, how should I display it properly ? When I try do something like :
data = db.getOccurations();
string = data.toString();
Log.e("Message",string);
I get : Message: android.database.sqlite.SQLiteCursor#1a81ae97 ofc it isn't data which I want get :)
How should I do it properly ?

For such debug logging purposes, have a look at DatabaseUtils#dumpCursorToString().
For non-debug purposes, call getString() et al. on the cursor.

try this:
while(data.moveToNext()){
String s = data.getString(data.getColumnIndex("column Name"));
}
or
while(data.moveToNext()){
String s = data.getString(0);
}

Reading a single value from a query is easier with a helper function, such as longForQuery() or stringForQuery():
public long getOccurations()
{
SQLiteDatabase db = getWritableDatabase();
return DatabaseUtils.longForQuery(db,
"select count(*) from Beacon_occurations where BEACON_ADDRESS=? and TIME=?",
new String[]{ COL_2, COL_3 });
}
But to count rows, there is an even easier helper function, queryNumEntries():
public long getOccurations()
{
SQLiteDatabase db = getWritableDatabase();
return DatabaseUtils.queryNumEntries(
db, "Beacon_occurations",
"BEACON_ADDRESS=? and TIME=?",
new String[]{ COL_2, COL_3 });
}

Related

Sqlite how to improve performance?

I have to make more than 300 selects from my database.
Each of those queries has to be called inside of a for each loop, here's an example:
for(int id : myids){
Cursor cursor = MyDatabaseHelper.runMyQuery(id);
while(cursor.moveToNext()){
//my stuff...
}
}
MyDatabaseHelper is an instance of a database helper class, the function is like this
public Cursor runMyQuery(int id){
SQLiteDatabase db = this.getWritableDatabase();
Cursor ret = db.rawQuery("select Name, Surname, Age from PTable where Id = " + id, null);
return ret;
}
I've been told that the constant "open and close" of the db because of multiple queries it the cause of my performance issues and I should, instead, make a single query (using union etc).
Changing my code to a single query would mean changing the entire database, and I was hoping not to do that.
Is there anything I can do to improve the performance and keep the multiple selects at the same time?
Thanks
I think what you are looking for is the in clause.
Convert your myids into a string. Something like
String inClause = "(1,2,3)"
and you can use it as
"select Name, Surname, Age from PTable where Id in " + inClause
You can read more of the in operator here
You can return a single Cursor containing all the rows.
First change your runMyQuery() method to this:
public Cursor runAll(String list){
SQLiteDatabase db = this.getWritableDatabase();
String sql = "select Name, Surname, Age from PTable where " + list + " like '%,' || id || ',%'"
Cursor ret = db.rawQuery(sql, null);
return ret;
}
So you pass to the method runAll() a String which is the the comma separated list of all the ids that you have in myids and with th eoperator LIKE you compare it to each id of the table.
You create this list and get the results in a Cursor object like this:
StringBuilder sb = new StringBuilder(",");
for(int id : myids){
sb.append(String.valueOf(id)).append(",");
}
String list = sb.length() > 1 ? sb.toString() : "";
if (list.length() > 0) {
Cursor c = runAll(list);
while(c.moveToNext()){
//your stuff...
}
}

my sql delete command makes my db.insert to cause a crash

public void(Budget budget){
SQLiteDatabase db = this.getReadableDatabase();
db.delete(Budget.table_name, Budget.collum_id, " = ?", new String[]{String.valueOf(budget.getId())}
}
You provided wrong parameters to delete method, right syntax is as below
delete(String table, String whereClause, String[] whereArgs)
if you are confused with this syntax simply use
db.execSQL(DELETE FROM table WHERE condition1 AND condition2.....);
change your code this way you are getting data for reading.
public void(Budget budget){
SQLiteDatabase db = this.getWritableDatabase();
db.delete(Budget.table_name, Budget.collum_id, " = ?", new String[]{String.valueOf(budget.getId())
db.close();}
}
Change to:
SQLiteDatabase db = this.getWriteableDatabase();
db.delete(Budget.table_name, Budget.collum_id + " = ?", new String[]{String.valueOf(budget.getId())});
You want to delete not read from the db
Also change to
Budget.collum_id + " = ?"

Android SqlLite check if two values exist in 2 different columns

I am developing an application where the user inputs title and the date. I want to prevent the duplicated titles being inputted on the same day in to database. I am checking if the title exists on the selected date. However my query seems not to work and i don't know why, the application just crashes.Is this query correct? Can someone help?
public boolean checkExist(String title, String date) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +"AND" + DATE+"=?", new String[] {title,date});
boolean exists = c.moveToFirst();
c.close();
return exists;
}
One issue that you have is that c.moveToFirst will always fail if a match does not exist as you are trying to move to a row in an empty cursor.
The resolution is to not use c.moveToFirst and instead get the count of the rows and then set the return value accordingly.
e.g.
public boolean checkExist(String title, String date) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +"AND" + DATE+"=?", new String[] {title,date});
boolean exists = c.getCount() > 0;
c.close();
return exists;
}
The second issue is that the query itself is wrong as you do not have spaces either side of the AND keyword. That is instead of
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +"AND" + DATE+"=?", new String[] {title,date});
You should have
Cursor c = db.rawQuery("SELECT * FROM "+TABLE_NAME+" WHERE "+TITLE+"=?" +" AND " + DATE+"=?", new String[] {title,date});
Personally, I setup constants for SQL keywords that include the space and then use these. So I'd have something along the lines of +TITLE+"=?" + SQLAND + DATE+"=?". Where SQLAND would be defined along the lines of String SQLAND=" AND ";
PS look at Cricket_007's answer, the code is neater/better it's easier to read.
Your spacing is off. TITLE+"=?" +"AND" + DATE becomes TITLE=?ANDDATE=?
I would suggest this. See DatabaseUtils.queryNumEntries
public boolean checkExist(String title, String date) {
SQLiteDatabase db = getReadableDatabase();
String[] args = new String[] {title,date};
String filter = String.format("%s=? AND %s=?", TITLE, DATE);
return DatabaseUtils.queryNumEntries(db, TABLE_NAME, filter, args) > 0;
}
you should be using c.getCount() instead of c.moveToFirst()
if the value is greater than 0, then it exists

The sql query does not pass the arguments

I'm writing an android application and I need to search the data base, this is the method I use:
public Cursor getData(String table, String keyword, SQLiteDatabase db){
String selection;
Cursor cursor;
switch (table){
case "User":
String [] projection = {id,name,phone};
selection = "username LIKE ?";
String [] selection_arg = {keyword};
cursor = db.query("User",projection,selection,selection_arg,null,null,null);
break;
//omitted
default:
return null;
}
return cursor;
The user put in the keyword
keyword = search_user.getText().toString();
Cursor cursor = dbHelper.getData(ShippingApplication.User.USER_TABLE,keyword,db);
The code does not work, when I debug, I see the mQuery of the db variable is:
SQLiteQuery: SELECT userID, userName, phoneNumber FROM User WHERE userName LIKE ?
It looks like the query does not pass the value of the keyword in to the sql command.
Could someone tell me what's wrong?
EDIT 2: I change the code a little bit and now it works:
String selection = ShippingApplication.User.name + " LIKE '%" + keyword + "%'";
Cursor cursor = db.query(The table name,projection,selection,null,null,null,null);
try this way
please check your SQLiteDatabase object is not null
after that check Table is created or not
i get the cursor count i already debug it and it's working fine for me
public Cursor getData(String table, String keyword, SQLiteDatabase db){
String selection;
Cursor cursor;
switch (table){
case "Tbl_staticContent":
String [] projection = {"PageTitle","Content"};
selection = "PageTitle LIKE ?";
String [] selection_arg = {keyword};
cursor = db.query("Tbl_staticContent",projection,selection,selection_arg,null,null,null);
Log.e("count",""+cursor.getCount());
//I have create table and stored data and also check the like condtion also it's work fine and get the cursor.getCount() > 0 also .
break;
default:
return null;
}
return cursor;
}

Method to excute query and return results

App won't run - trying to execute query to print certain value
Method:
public Cursor trying(String vg){
String q="SELECT quantity FROM " + TABLE_CONTACTS + " WHERE name=" + vg;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(q,null);
if (cursor != null) {
cursor.moveToFirst();
}
return cursor;
}
Calling method from main
Cursor wow = db.trying("gold");
text = (TextView) findViewById(R.id.textView13);
text.setText((CharSequence) (wow));
At first. Since you are directly adding trying variables into statement, variable must be wrapped to single quotes or it's interpeted as column.
"SELECT quantity FROM " + TABLE_CONTACTS + " WHERE name= '" + vg + "'";
And second "big" problem, look here:
text.setText((CharSequence) (wow));
Here you are trying to cast Cursor to CharSequence but it's not possible. If you want to retrieve data from Cursor you have to use one from the getters methods of Cursor class in your case getString() method:
String quantity = wow.getString(0); // it returns your quantity from Cursor
text.setText(quantity);
Now it should works.
Recommendation:
I suggest you to an usage of parametrized statements which actually use placeholders in your queries. They provide much more safer way for adding and retrieving data to / from database.
Let's rewrite your code:
String q = "SELECT quantity FROM " + TABLE_CONTACTS + " WHERE name = ?";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(q, new String[] {vg});
It works simply. Placeholder ? will be replaced with your string value.

Categories

Resources