How to get row count in sqlite using Android? - android

I am creating task manager. I have tasklist and I want when I click on particular tasklist name if it empty then it goes on Add Task activity but if it has 2 or 3 tasks then it shows me those tasks into it in list form.
I am trying to get count in list. my database query is like:
public Cursor getTaskCount(long tasklist_Id) {
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor= db.rawQuery("SELECT COUNT (*) FROM " + TABLE_TODOTASK + " WHERE " + KEY_TASK_TASKLISTID + "=?",
new String[] { String.valueOf(tasklist_Id) });
if(cursor!=null && cursor.getCount()!=0)
cursor.moveToNext();
return cursor;
}
In My activity:
list_tasklistname.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0,
android.view.View v, int position, long id) {
db = new TodoTask_Database(getApplicationContext());
Cursor c = db.getTaskCount(id);
System.out.println(c.getCount());
if(c.getCount()>0) {
System.out.println(c);
Intent taskListID = new Intent(getApplicationContext(), AddTask_List.class);
task = adapter.getItem(position);
int taskList_id = task.getTaskListId();
taskListID.putExtra("TaskList_ID", taskList_id);
startActivity(taskListID);
}
else {
Intent addTask = new Intent(getApplicationContext(), Add_Task.class);
startActivity(addTask);
}
}
});
db.close();
}
but when I am clicking on tasklist name it is returning 1, bot number of tasks into it.

Using DatabaseUtils.queryNumEntries():
public long getProfilesCount() {
SQLiteDatabase db = this.getReadableDatabase();
long count = DatabaseUtils.queryNumEntries(db, TABLE_NAME);
db.close();
return count;
}
or (more inefficiently)
public int getProfilesCount() {
String countQuery = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int count = cursor.getCount();
cursor.close();
return count;
}
In Activity:
int profile_counts = db.getProfilesCount();
db.close();

Use android.database.DatabaseUtils to get number of count.
public long getTaskCount(long tasklist_Id) {
return DatabaseUtils.queryNumEntries(readableDatabase, TABLE_NAME);
}
It is easy utility that has multiple wrapper methods to achieve database operations.

c.getCount() returns 1 because the cursor contains a single row (the one with the real COUNT(*)). The count you need is the int value of first row in cursor.
public int getTaskCount(long tasklist_Id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor= db.rawQuery(
"SELECT COUNT (*) FROM " + TABLE_TODOTASK + " WHERE " + KEY_TASK_TASKLISTID + "=?",
new String[] { String.valueOf(tasklist_Id) }
);
int count = 0;
if(null != cursor)
if(cursor.getCount() > 0){
cursor.moveToFirst();
count = cursor.getInt(0);
}
cursor.close();
}
db.close();
return count;
}

I know it is been answered long time ago, but i would like to share this also:
This code works very well:
SQLiteDatabase db = this.getReadableDatabase();
long taskCount = DatabaseUtils.queryNumEntries(db, TABLE_TODOTASK);
BUT what if i dont want to count all rows and i have a condition to apply?
DatabaseUtils have another function for this: DatabaseUtils.longForQuery
long taskCount = DatabaseUtils.longForQuery(db, "SELECT COUNT (*) FROM " + TABLE_TODOTASK + " WHERE " + KEY_TASK_TASKLISTID + "=?",
new String[] { String.valueOf(tasklist_Id) });
The longForQuery documentation says:
Utility method to run the query on the db and return the value in the first column of the first row.
public static long longForQuery(SQLiteDatabase db, String query, String[] selectionArgs)
It is performance friendly and save you some time and boilerplate code
Hope this will help somebody someday :)

Change your getTaskCount Method to this:
public int getTaskCount(long tasklist_id){
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor= db.rawQuery("SELECT COUNT (*) FROM " + TABLE_TODOTASK + " WHERE " + KEY_TASK_TASKLISTID + "=?", new String[] { String.valueOf(tasklist_id) });
cursor.moveToFirst();
int count= cursor.getInt(0);
cursor.close();
return count;
}
Then, update the click handler accordingly:
public void onItemClick(AdapterView<?> arg0, android.view.View v, int position, long id) {
db = new TodoTask_Database(getApplicationContext());
// Get task list id
int tasklistid = adapter.getItem(position).getTaskListId();
if(db.getTaskCount(tasklistid) > 0) {
System.out.println(c);
Intent taskListID = new Intent(getApplicationContext(), AddTask_List.class);
taskListID.putExtra("TaskList_ID", tasklistid);
startActivity(taskListID);
} else {
Intent addTask = new Intent(getApplicationContext(), Add_Task.class);
startActivity(addTask);
}
}

In order to query a table for the number of rows in that table, you want your query to be as efficient as possible. Reference.
Use something like this:
/**
* Query the Number of Entries in a Sqlite Table
* */
public long QueryNumEntries()
{
SQLiteDatabase db = this.getReadableDatabase();
return DatabaseUtils.queryNumEntries(db, "table_name");
}

Do you see what the DatabaseUtils.queryNumEntries() does? It's awful!
I use this.
public int getRowNumberByArgs(Object... args) {
String where = compileWhere(args);
String raw = String.format("SELECT count(*) FROM %s WHERE %s;", TABLE_NAME, where);
Cursor c = getWriteableDatabase().rawQuery(raw, null);
try {
return (c.moveToFirst()) ? c.getInt(0) : 0;
} finally {
c.close();
}
}

Sooo simple to get row count:
cursor = dbObj.rawQuery("select count(*) from TABLE where COLUMN_NAME = '1' ", null);
cursor.moveToFirst();
String count = cursor.getString(cursor.getColumnIndex(cursor.getColumnName(0)));

looking at the sources of DatabaseUtils we can see that queryNumEntries uses a select count(*)... query.
public static long queryNumEntries(SQLiteDatabase db, String table, String selection,
String[] selectionArgs) {
String s = (!TextUtils.isEmpty(selection)) ? " where " + selection : "";
return longForQuery(db, "select count(*) from " + table + s,
selectionArgs);
}

Once you get the cursor you can do
Cursor.getCount()

Related

Sqlite Local database is not accurate

I'm developing android application and I'm storing some data in the local database using sqlite. When I save the database from the device file explorer and browse it using DB browser for sqlite it shows many records there which are correct. BUT i have implement a function that count number of records for specific table and it returns 0 which is wrong value.
I'm lost now cause I think the function is correct
public int numOfRecords(String tableName) {
int numOfRecords = 0;
try {
String query = "SELECT COUNT(*) FROM " + tableName ;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
if (cursor != null && cursor.moveToFirst()) {
numOfRecords = cursor.getInt(0);
}
db.close();
}
catch (Exception ex ) {
Log.d("test" , "In exception");
}
return numOfRecords;
}
Try this code
public long getProfilesCount() {
SQLiteDatabase db = this.getReadableDatabase();
long count = DatabaseUtils.queryNumEntries(db, TABLE_NAME);
db.close();
return count;
}
Or
public int getProfilesCount() {
String countQuery = "SELECT * FROM " + TABLE_NAME;
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(countQuery, null);
int count = cursor.getCount();
cursor.close();
return count;
}

Retrieving specific data based on ID from SQLite in ANDROID

I wrote a code in which i can retrieve the data from the database but when i run it and try to search something. The application crashes as soon as i press Submit
public class search extends AppCompatActivity {
Button SearchButton;
EditText SearchText;
TextView SearchResult;
SQLiteDatabase db;
String builder;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.search);
SearchButton=(Button)findViewById(R.id.searchbutton);
SearchText=(EditText)findViewById(R.id.Searchtext);
SearchResult=(TextView)findViewById(R.id.SearchCourse);
db=this.openOrCreateDatabase("Courses", Context.MODE_PRIVATE,null);
SearchButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
int GetID = Integer.valueOf(SearchText.getText().toString());
Cursor TuplePointer = db.rawQuery("Select from Course where ID="+GetID+"",null);
TuplePointer.moveToFirst();
String Course = TuplePointer.getString(TuplePointer.getColumnIndex("Course"));
SearchResult.setText(Course);
}
});
}
}
Replace this line
Cursor TuplePointer = db.rawQuery("Select from Course where ID=" + GetID + "", null);
with
Cursor TuplePointer = db.rawQuery("Select Course from Course where ID=" + GetID + "", null);
Where Course is your column name
Write your code within try catch first. Afterthat try to catch exact exception. you will be clear what are you doing wrong.
String selectQuery = "SELECT * FROM " + TABLE_CONTACTS + " Where " + KEY_APP_BOOKINGID + " = " + id;
Cursor cursor = db.rawQuery(selectQuery, null);
Please Try this
SQLiteDatabase db = this.getReadableDatabase();
String GetID = SearchText.getText().toString();
Cursor cursor = db.rawQuery("SELECT * FROM Course WHERE ID = ?", new String[]{String.valueOf(GetID)}, null);
if (cursor.moveToFirst()) {
do {
String Course = cursor.getString(cursor.getColumnIndex("Course"));
SearchResult.setText(Course);
} while (cursor.moveToNext());
}
Thank You everyone I figured out what i was doing wrong on the get Column index i targeted course but what i didnt realize is that there was no such field as course :)
Keep practice like below code you will debug proper
public void getFirstName(String id) {
String sql = "select first_name from basic_info WHERE contact_id="+ id;
Cursor c = fetchData(sql);
if (c != null) {
while (c.moveToNext()) {
String FirstName = c.getString(c.getColumnIndex("first_name"));
Log.e("Result =>",FirstName);
}
c.close();
}
return data;
}
public Cursor fetchData(String sql) {
SQLiteDatabase db = this.getWritableDatabase();
return db.rawQuery(sql, null);
}

Android : How to create Cursor object to get item id in SQLite?

How to create cursor object to get item id from database?
Here is my method of DBHelper, see the Cursor method
public int getItemIdByPosition(int position) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from " + TABLE_NAME, null);
cursor.moveToPosition(position);
return Integer.parseInt(cursor.getString(0));
}
Seems to be correct.
Maybe the position passed through method is not correct, maybe is more efficient is you use, instead of pass a position on your method pass the ID:
"select * from " + TABLE_NAME + " where id = " = id
Also you can use:
cursor.getColumnIndex(COLUMN_NAME) instead of cursor.getString(0)
Your code seems to be right, I just would check the below things that I mentioned.
String selectQuery = "SELECT * FROM " + TABLE_NAME + " WHERE " + POSITION + " = " + position;
db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
int userId;
if (cursor.moveToFirst())
{
userId = cursor.getInt(0);
}
cursor.close();
return userId;
This is a sample code hope you can get a help from this
private void displayListView(String getter){
//get the customer data from the db and feed them to cursor and load the data to lest
Cursor cursor = dbHelper.fetchallcustomercompany(getter);
String[] columns = new String[] {
//get the needed columns of the db and feed them in to string array
DBCreater.Key_customer_Shop
};
int[] to = new int[]{
//get the textboxs in xml layout,which going to display the values in to integer array
R.id.tv_demo_search_text_Isuru
};
//address the xml list view to java
final ListView listView = (ListView)findViewById(R.id.lv_searchcustomer_cuzlist_Isuru);
// feed the context,displaying layout,data of db, data source of the data and distination of the data
if(cursor.getCount()==0){
Toast.makeText(getApplicationContext(), " No matching data", Toast.LENGTH_SHORT).show();
}
else{
dataAdapter = new SimpleCursorAdapter(this, R.layout.demo_search, cursor, columns, to,0);
//load the data to list view
listView.setAdapter(dataAdapter);
//what happen on when user click on the item of the list view
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
Cursor cursor =(Cursor)listView.getItemAtPosition(arg2);
//get the value of the customer name from the clicked listitem
String name=cursor.getString(cursor.getColumnIndexOrThrow("customer_shop"));
}
});
}
}
Try this:
public int getItemIdByPosition(int position) {
int itemID = 0;
Cursor localCursor = database.rawQuery("select * from " + TABLE_NAME,
null);
int i = localCursor.getColumnIndex("ID");
if (localCursor.moveToFirst()) {
do {
itemID = Integer.parseInt(localCursor.getString(i));
} while (localCursor.moveToPosition(position));
}
localCursor.close();
return itemID;
}

SQLite search by name, show sum result in textfield

I have a code that would give me the sum of a column in a database, i have done the crud, but now i would like to do a search by a the name of a column and show the sum of all the records(that have the same name) and show in a textfield.
the following is my DatabasdeHandler:
public Cursor getSingleDespesaSum(String date) {
SQLiteDatabase db = this.getReadableDatabase();
int sum = 0;
Cursor cursor = db.rawQuery(
"select sum(valor) from despesas WHERE data = ?", null);
if (cursor.moveToFirst()) {
do {
sum = cursor.getInt(0);
} while (cursor.moveToNext());
}
return cursor;
}
And this is my activity;
btGetSum.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
try {
dia = (String) spinDia.getSelectedItem();
mes = (String) spinMes.getSelectedItem();
ano = (String) spinAno.getSelectedItem();
String dataSendTo = dia + "/" + mes + "/" + ano;
dbhelper.getSingleDespesaSum(dataSendTo); //missing code
} catch (Exception erro) {
mensagemExibir("Erro Ao Buscar", "" + erro.getMessage());
}
}
});
}
Content Providers are the way to go, don't access your database directly like this.
But... to answer your current question:
SQLiteDatabase db = this.getReadableDatabase();
int sum = 0;
Cursor cursor = db.rawQuery(
"select value from table WHERE date= ?", null);
while (cursor.moveToNext()) {
//Increment your counter
sum += cursor.getInt(cursor.getColumnIndex("value");
};

Android sqlite how to check if a record exists

I would like to check whether a record exists or not.
Here is what I've tried:
MainActivity.class
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Ontext changed " + new String(s.toString()));
strDocumentFrom = s.toString();
if(s.toString().isEmpty()){
} else {
try{
strTransactionDate = dbHelper.getTransactionDateByDocumentNumber(strDocumentFrom);
//strTotalAmount = dbHelper.getTotalAmountByDocumentNumber(strDocumentFrom);
//strVan = dbHelper.getVanByDocumentNumber(strDocumentFrom);
//etTransactionDate.setText(strTransactionDate);
//etTotalAmount.setText(strTotalAmount);
//Log.d("Van", "" + strVan);
//etVan.setText(strVan);
} catch (SQLiteException e) {
e.printStackTrace();
Toast.makeText(ReceivingStocksHeader.this,
"Document number does not exist.", Toast.LENGTH_SHORT).show();
}
}
DBHelper.class
// TODO DISPLAYING RECORDS TO TRANSRCVHEADER
public String getTransactionDateByDocumentNumber(String strDocumentNumber){
String[] columns = new String[]{KEY_TRANSACTIONDATE};
Cursor c = myDataBase.query(TBL_INTRANS,
columns, null,
null, null, null, null, null);
if(c != null){
c.moveToFirst();
String date = c.getString(0);
return date;
} else {
Log.d("Error", "No record exists");
}
return null;
}
But it doesn't get it to the catch block to display the toast.
What am I doing wrong in here?
public static boolean CheckIsDataAlreadyInDBorNot(String TableName,
String dbfield, String fieldValue) {
SQLiteDatabase sqldb = EGLifeStyleApplication.sqLiteDatabase;
String Query = "Select * from " + TableName + " where " + dbfield + " = " + fieldValue;
Cursor cursor = sqldb.rawQuery(Query, null);
if(cursor.getCount() <= 0){
cursor.close();
return false;
}
cursor.close();
return true;
}
I hope this is useful to you...
This function returns true if record already exists in db. Otherwise returns false.
These are all good answers, however many forget to close the cursor and database. If you don't close the cursor or database you may run in to memory leaks.
Additionally: You can get an error when searching by String that contains non alpha/numeric characters. For example: "1a5f9ea3-ec4b-406b-a567-e6927640db40". Those dashes (-) will cause an unrecognized token error. You can overcome this by putting the string in an array. So make it a habit to query like this:
public boolean hasObject(String id) {
SQLiteDatabase db = getWritableDatabase();
String selectString = "SELECT * FROM " + _TABLE + " WHERE " + _ID + " =?";
// Add the String you are searching by here.
// Put it in an array to avoid an unrecognized token error
Cursor cursor = db.rawQuery(selectString, new String[] {id});
boolean hasObject = false;
if(cursor.moveToFirst()){
hasObject = true;
//region if you had multiple records to check for, use this region.
int count = 0;
while(cursor.moveToNext()){
count++;
}
//here, count is records found
Log.d(TAG, String.format("%d records found", count));
//endregion
}
cursor.close(); // Dont forget to close your cursor
db.close(); //AND your Database!
return hasObject;
}
Raw queries are more vulnerable to SQL Injection. I will suggest using query() method instead.
public boolean Exists(String searchItem) {
String[] columns = { COLUMN_NAME };
String selection = COLUMN_NAME + " =?";
String[] selectionArgs = { searchItem };
String limit = "1";
Cursor cursor = db.query(TABLE_NAME, columns, selection, selectionArgs, null, null, null, limit);
boolean exists = (cursor.getCount() > 0);
cursor.close();
return exists;
}
Source: here
SELECT EXISTS with LIMIT 1 is much faster.
Query Ex: SELECT EXISTS (SELECT * FROM table_name WHERE column='value' LIMIT 1);
Code Ex:
public boolean columnExists(String value) {
String sql = "SELECT EXISTS (SELECT * FROM table_name WHERE column='"+value+"' LIMIT 1)";
Cursor cursor = database.rawQuery(sql, null);
cursor.moveToFirst();
// cursor.getInt(0) is 1 if column with value exists
if (cursor.getInt(0) == 1) {
cursor.close();
return true;
} else {
cursor.close();
return false;
}
}
You can use SELECT EXISTS command and execute it for a cursor using a rawQuery,
from the documentation
The EXISTS operator always evaluates to one of the integer values 0
and 1. If executing the SELECT statement specified as the right-hand
operand of the EXISTS operator would return one or more rows, then the
EXISTS operator evaluates to 1. If executing the SELECT would return
no rows at all, then the EXISTS operator evaluates to 0.
I have tried all methods mentioned in this page, but only below method worked well for me.
Cursor c=db.rawQuery("SELECT * FROM user WHERE idno='"+txtID.getText()+"'", null);
if(c.moveToFirst())
{
showMessage("Error", "Record exist");
}
else
{
// Inserting record
}
One thing the top voted answer did not mention was that you need single quotes, 'like this', around your search value if it is a text value like so:
public boolean checkIfMyTitleExists(String title) {
String Query = "Select * from " + TABLE_NAME + " where " + COL1 + " = " + "'" + title + "'";
Cursor cursor = database.rawQuery(Query, null);
if(cursor.getCount() <= 0){
cursor.close();
return false;
}
cursor.close();
return true;
}
Otherwise, you will get a "SQL(query) error or missing database" error like I did without the single quotes around the title field.
If it is a numeric value, it does not need single quotes.
Refer to this SQL post for more details
SQLiteDatabase sqldb = MyProvider.db;
String Query = "Select * from " + TABLE_NAME ;
Cursor cursor = sqldb.rawQuery(Query, null);
cursor.moveToLast(); //if you not place this cursor.getCount() always give same integer (1) or current position of cursor.
if(cursor.getCount()<=0){
Log.v("tag","if 1 "+cursor.getCount());
return false;
}
Log.v("tag","2 else "+cursor.getCount());
return true;
if you not use cursor.moveToLast();
cursor.getCount() always give same integer (1) or current position of cursor.
Code :
private String[] allPushColumns = { MySQLiteHelper.COLUMN_PUSH_ID,
MySQLiteHelper.COLUMN_PUSH_TITLE, MySQLiteHelper.COLUMN_PUSH_CONTENT, MySQLiteHelper.COLUMN_PUSH_TIME,
MySQLiteHelper.COLUMN_PUSH_TYPE, MySQLiteHelper.COLUMN_PUSH_MSG_ID};
public boolean checkUniqueId(String msg_id){
Cursor cursor = database.query(MySQLiteHelper.TABLE_PUSH,
allPushColumns, MySQLiteHelper.COLUMN_PUSH_MSG_ID + "=?", new String [] { msg_id }, null, null, MySQLiteHelper.COLUMN_PUSH_ID +" DESC");
if(cursor.getCount() <= 0){
return false;
}
return true;
}
Here's a simple solution based on a combination of what dipali and Piyush Gupta posted:
public boolean dbHasData(String searchTable, String searchColumn, String searchKey) {
String query = "Select * from " + searchTable + " where " + searchColumn + " = ?";
return getReadableDatabase().rawQuery(query, new String[]{searchKey}).moveToFirst();
}
because of possible data leaks best solution via cursor:
Cursor cursor = null;
try {
cursor = .... some query (raw or not your choice)
return cursor.moveToNext();
} finally {
if (cursor != null) {
cursor.close();
}
}
1) From API KITKAT u can use resources try()
try (cursor = ...some query)
2) if u query against VARCHAR TYPE use '...' eg. COLUMN_NAME='string_to_search'
3) dont use moveToFirst() is used when you need to start iterating from beggining
4) avoid getCount() is expensive - it iterates over many records to count them. It doesn't return a stored variable. There may be some caching on a second call, but the first call doesn't know the answer until it is counted.
Try to use cursor.isNull method.
Example:
song.isFavorite = cursor.isNull(cursor.getColumnIndex("favorite"));
You can use like this:
String Query = "Select * from " + TABLE_NAME + " where " + Cust_id + " = " + cust_no;
Cursor cursorr = db.rawQuery(Query, null);
if(cursor.getCount() <= 0){
cursorr.close();
}
cursor.close();
private boolean checkDataExistOrNot(String columnName, String value) {
SQLiteDatabase sqLiteDatabase = getReadableDatabase();
String query = "SELECT * FROM" + TABLE_NAME + " WHERE " + columnName + " = " + value;
Cursor cursor = sqLiteDatabase.rawQuery(query, null);
if (cursor.getCount() <= 0) {
cursor.close();
return false; // return false if value not exists in database
}
cursor.close();
return true; // return true if value exists in database
}
I prefer to do it this way because it's fast and less expensive than other methods:
Cursor cursor = db.rawQuery("SELECT 1 FROM table WHERE condition = 1 LIMIT 1", null);
try {
if (cursor.moveToNext()) {
//Record exists
} else {
//Record doesn't exists
}
} finally {
cursor.close();
}
My version:
public boolean isTitleExists(String title, String type) {
int isExists = 0;
try {
String query = "SELECT EXISTS (SELECT 1 FROM titles WHERE title = ? and type = ?)";
PreparedStatement statement = connection.prepareStatement(query);
statement.setString(1, title);
statement.setString(2, type);
ResultSet rs = statement.executeQuery();
rs.next();
isExists = rs.getInt(1);
rs.close();
statement.close();
} catch (SQLException e) {
Common.console("isTitleExists error: " + e.getMessage());
}
return isExists == 1;
}

Categories

Resources