I want to add a new item (spot) in my database, but before doing this, I want to check if this item already exists.
Here is my code :
for (Spot spot : spotsList)
{
if (dbHelper.getSpotWithDistantId(spot.getDistantId()) == null)
{
dbHelper.addSpot(spot);
}
}
And here is my getSpotWithDistantId method :
public Spot getSpotWithDistantId(int distantId)
{
Cursor cursor =
db.query(TABLE_SPOTS,
SPOTS_COLUMNS,
" " + KEY_DISTANTID + " = ?",
new String[]{String.valueOf(distantId)}, // Selections args
null, // Group by
null, // Having
null, // Order by
null); // Limit
if (cursor != null)
{
cursor.moveToFirst();
}
Spot spot = buildSpotWithCursor(cursor);
if (cursor != null)
{
cursor.close();
}
db.close();
return spot;
}
The problem is when I want to check if a spot exists, the following error appears:
android.database.CursorIndexOutOfBoundsException: Index 0 requested,
with a size of 0
What's wrong with my code ?
Thanks in advance.
You need to check if your cursor contains any records. You can do it like this
if(cursor != null && cursor.getCount() > 0)
{
...
}
else
{
cursor.close();
return false;
}
I have the similar problem and I use this simple function:
public boolean exists_the_ColumnParameter(String query){
//Declaration of variables
Cursor a2 = null;
try{
OpenDB();
a2 = database.rawQuery(query,null);
if(a2 != null) {
a2.moveToFirst();
if (a2.getString(0).equals("")) {
a2.close();
database.close();
return false;
} else {
a2.close();
database.close();
return true;
}
}else{
a2.close();
database.close();
return false;
}
}
catch (CursorIndexOutOfBoundsException ex){
return false;
}
catch (NullPointerException ex){
return false;
}
catch (Exception ex){
Log.e("-- BDD.exists_the_ColumnParameter --","Exception",ex);
return false;
}
}
The reason which I can't pass a single ID because it isn't a generic function, the big difference is which with the ID you can only view one SQLite table and with the query you can view multiple ID's from diferent tables.
Tell me if I can helps you, good programming!!
Related
I use code below to test if a column exists:
public static boolean isColumnExists(String tableName, String columnName) {
Cursor cursor = null;
try {
SQLiteDatabase db = getDatabase();
cursor = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 0", null);
String[] cloNames = cursor.getColumnNames();
if (cloNames != null) {
for (String temp : cloNames) {
if (columnName.equalsIgnoreCase(temp)) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != cursor && !cursor.isClosed()) {
cursor.close();
}
}
return false;
}
The column hello2 doesn't exist in initial state, after adding column to database, the following test still tells that the column doesn't exist, and the second try will cause an error about duplicate column, which is not correct.
if (!isColumnExists("PositionCache", "hello2")) {
// First try will insert column to database
getDatabase().execSQL("alter table PositionCache add hello2 Integer default 0");
}
if (!isColumnExists("PositionCache", "hello2")) {
// Second try will give and error about duplicate column of hello2
getDatabase().execSQL("alter table PositionCache add hello2 Integer default 0");
}
I need to know the reason about such an abnormal phenomenon.
If I change SELECT * FROM to select * from in method isColumnExists then everything become normal.
I believe the reason is that SQLite (I strongly suspect the Cursor, so more correctly the Android SQLite aspect of the SDK) is cacheing data (perhaps because the underlying data is never retrieved from the Database as there is no need to get the data (as far as the Cursor is concerned)).
I've tried various checks including putting breakpoints in, checking the result of getColumnnames, and making the method non-static.
As soon as I add an alternative check using the PRAGMA table_info(*table_name*); then the column exists.
As such I'd suggest using the following :-
public static boolean isColumnExistsOld(String tableName, String columnName) {
Cursor csr = getDatabase().rawQuery("PRAGMA table_info(" + tableName + ")",null);
while(csr.moveToNext()) {
if (csr.getString(csr.getColumnIndex("name")).equalsIgnoreCase(columnName)) {
return true;
}
}
return false;
/*
Cursor cursor = null;
try {
SQLiteDatabase db = getDatabase();
cursor = db.rawQuery("SELECT * FROM " + tableName + " LIMIT 1", null);
cursor.moveToFirst();
String[] cloNames = cursor.getColumnNames();
if (cloNames != null) {
for (String temp : cloNames) {
if (columnName.equalsIgnoreCase(temp)) {
return true;
}
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != cursor && !cursor.isClosed()) {
cursor.close();
}
}
boolean rv = colfound;
return false;
*/
}
Note your code has been left in but commented out.
I believe that evaluating forces the cache to be refreshed (i.e. I tried this an yep it does dynamically change to include the column).
I am making a media player which loads metadata of songs into a database.
Below is my function for checking whether the db is empty or not but it isn't working. Please tell me what's wrong with my code and suggest a correction or a better alternative.
private static boolean isDbEmpty(SQLiteDatabase songsDb) {
try {
Cursor c = songsDb.rawQuery("SELECT * FROM " + SongsTable.TABLE_NAME, null);
if (c.moveToFirst()) { // c.getCount() == 0 is also not working
Log.d(TAG, "isDbEmpty: not empty");
return false;
}
c.close();
} catch (SQLiteException e) {
Log.d(TAG, "isDbEmpty: doesn't exist");
return true;
}
return true;
}
Use the following query to achieve your goal. There are two tables created automatically - android_metadata and sqlite_sequence, so we apply a NOT condition in the query.
SELECT count(*) FROM sqlite_master WHERE type = 'table' AND name != 'android_metadata' AND name != 'sqlite_sequence';
Try this.
private static boolean isDbEmpty(SQLiteDatabase songsDb) {
Cursor c = null;
try {
c = songsDb.rawQuery("SELECT * FROM " + SongsTable.TABLE_NAME, null);
if (c == null || c.getCount() == 0) {
return true;
} else if (c.moveToFirst()) {
Log.d(TAG, "isDbEmpty: not empty");
return false;
}
} catch (SQLiteException e) {
Log.d(TAG, "isDbEmpty: doesn't exist");
return true;
}finally {
if(c != null){
c.close();
}
}
return true;
}
This will only tell you if the TABLE is empty, not the DATABASE.
Regardless, you could use code like:
Cursor countCursor = songsDb.rawQuery("select count(*) from " + SongsTable.TABLE_NAME, null);
countCursor.moveToFirst();
int count = countCursor.getInt(0);
countCursor.close();
And then test count.
You can check like this :
Cursor c = songsDb.rawQuery("SELECT * FROM " + SongsTable.TABLE_NAME, null);
cursor.moveToFirst();
if (cursor != null && cursor.getCount() == 0) {
//for empty
return true;
}else{
// not empty
return false;
}
i'm working sqlite.i want to check if table is empty.i wrote some code but my code does not working perfect
this is a my DatabaseHelper code (function)
public boolean CheckGenderTableEmpty() {
boolean isEmpty = false;
String count = "SELECT * FROM Gender";
Cursor mcursor = db.rawQuery(count, null);
mcursor.moveToFirst();
if (mcursor.getCount() != 0) {
if (!mcursor.isClosed())
{
mcursor.close();
Log.e("is not empty", "is not empty");
isEmpty=true;
}
} else {
if (!mcursor.isClosed())
{
mcursor.close();
Log.e(" empty", "empty");
isEmpty=false;
}
}
return isEmpty;
}
as i said my code does not working perfect.first time my table is empty and i can't show log message about empty
and i call my function activity like this..
if(db_helper.CheckGenderTableEmpty()==true)
{
Toast.makeText(getApplicationContext(), "is not empty", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(), "empty", Toast.LENGTH_SHORT).show();
}
how i can check if database is empty in activity?
if anyone knows solution please help me
Use getCount() method of Cursor:
public boolean IsTableEmpty(Cursor cursor) {
return !(cursor.getCount() > 0);
}
The Android framework has a helper function for this in the DatabaseUtils class:
public boolean CheckGenderTableEmpty() {
return DatabaseUtils.queryNumEntries(db, "Gender") == 0;
}
you can go with something like
SQLiteDatabase db = table.getWritableDatabase();
String count = "SELECT count(*) FROM Gender";
Cursor mcursor = db.rawQuery(count, null);
mcursor.moveToFirst();
int icount = mcursor.getInt(0);
if(icount>0)
//do accordingly
else
//do accordingly
cursor.moveToFirst(); // Always one row returned.
Then check cursor.getInt (0) == 0
if(cursor.getInt (0) == 0) // Zero count means empty table.
Try this.
I'm new to android development so I don't have much idea to how can handle this problem.
I have a problem with extract part in my codes, I want to get all rows of my table but here is some problem with boolean type
public ArrayList<UserMealUnit> getUserMealUnit() {
ArrayList<UserMealUnit> result = null;
SQLiteDatabase myDataBase = null;
Cursor cursor = null;
try {
myDataBase = openHelper.getWritableDatabase();
cursor = myDataBase.query(TABLE_USERMEALUNIT, new String[] { "*" }, null, null,
null, null, null);
if (cursor.moveToFirst()) {
result = new ArrayList<UserMealUnit>();
do {
result.add(extractUserMealUnit(cursor));
} while (cursor.moveToNext());
}
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
finally {
if (cursor != null) {
cursor.close();
}
myDataBase.close();
}
return result;
}
//extract
private UserMealUnit extractUserMealUnit(Cursor cursor) {
UserMealUnit usermealunit = new UserMealUnit();
boolean value1;
usermealunit.setMealid(cursor.getInt(cursor.getColumnIndex(TABLE_USERMEALUNIT_ID)));
usermealunit.setBreakfast(cursor.getInt(cursor.getColumnIndex(TABLE_USERMEALUNIT_BREAKFAST)));
return usermealunit;
}
breakfast type is boolean but cursor.getInt(cursor.getColumnIndex(TABLE_USERMEALUNIT_BREAKFAST) return int and here is the problem. I search about this problem but cant find anything useful. can any one help me?
There is no boolean type in SQLite database. Instead, you must save 0 as false and 1 as true. Thus to read your value
final boolean breakfast = cursor.getInt(cursor.getColumnIndex(TABLE_USERMEALUNIT_BREAKFAST) != 0;
When using the ContentValues the system will convert the Boolean into int for you automatically when saving.
contentValues.put(TABLE_USERMEALUNIT_BREAKFAST, booleanValue);
In my android app am trying to get values from database by passing one parameter to the where clause but it is always returning null...and theres no error in logcat...
i cant seem to figure out what is the issue here??
Please help!
the code where i am callimg the database function:
appmname=mDbHelper.getMname(appName);
applname=mDbHelper.getLname(appmname);
customername=appName+appmname+applname;
// app_formno=mDbHelper.getAppno(settings.getString("ap_First_Name", ""));
s=mDbHelper.fetchDetails(appName);
s=mDbHelper.getMainData(customername);
these are the functions returning database values:
public String getMname(String fname)
{
String mname = null;
try
{
String sql="select app_mname from lnt_data_table where app_fname = '"+fname+"'";
Cursor c=mDb.rawQuery(sql, null);
if (c != null) {
c.moveToFirst();
while (!c.isAfterLast()) {
mname=c.getString(0);
}
c.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
return mname;
}
public String getLname(String mname)
{
String lname = null;
try
{
String sql="select app_lname from lnt_data_table where app_mname= '"+mname+"'";
Cursor c=mDb.rawQuery(sql, null);
if (c != null) {
c.moveToLast();
while (c.isBeforeFirst() != true) {
lname=c.getString(0);
}
c.close();
}
}
catch(Exception e)
{
e.printStackTrace();
}
return lname;
}
if i give this toast message
Toast.makeText(ListViewDetails.this,appName+ appmname +applname, Toast.LENGTH_LONG).show();
it returns null when the database has values in it!
Try this format for calling the cursor and closing it
if (cursor != null) {
if (cursor.moveToFirst()) {
do {
//your code
}
while (cursor.moveToNext());
}
cursor.close();
Hope it helps :)
I think you are moving to the end of the cursor before actually getting anything from it. Try changing c.moveToLast(); to c.moveToFirst() and then in the while loop just change while (c.isBeforeFirst()) to while(!c.isAfterLast())
You are currently moving to the end of the cursor and then checking if its at a position before the first entry...which is kinda impossible. Probably why you aren't getting anything back