Update method returns true.
But when listing the whole table, new rows were created for each update.
ONE table, three columns: PRIMARY_ID, MY_ID, MY_ANOTHER_ID.
I have the following methods:
public void insertOrUpdate(String lStringId){
boolean present= search(lStringId);
if(present){
updateData(lStringId);
} else{
insertData(lStringId);
}
}
Search:
private boolean search(String lStringId) {
Cursor cursor = null;
try {
cursor = mDatabase.query(TABLE_NAME, null,
MY_ID + " = ?", new String[]{lStringId}, null, null, null);
if (null != cursor && cursor.getCount() == 1 && cursor.moveToFirst()) {
return true
}
Log.d(TAG, "-search, cursor.getCount() = " + cursor.getCount());
return false;
} catch (Exception e) {
Log.e(TAG, "-search, Error: "+ e.getLocalizedMessage());
return false;
} finally {
if (null != cursor) {
cursor.close();
cursor = null;
}
}
}
Update:
public boolean updateData(String lStringId) {
Log.d(TAG, " -updateData");
ContentValues lValues = new ContentValues();
lValues.put(MY_ANOTHER_ID, lStringId+"extra");
if (mDatabase.update(TABLE_NAME,
lValues, MY_ID + "= '" + lStringId + "'", null) > 0) {
Log.d(TAG, " -updateData, true");
return true;
}
return false;
}
Insert:
public long insertData(String lStringId) {
Log.d(TAG, " -insertData");
ContentValues dataValues = new ContentValues();
dataValues.put(MY_ID, lStringId);
long result = mDatabase.insert(TABLE_NAME, null, dataValues);
Log.d(TAG, "result: " + result);
return result;
}
After the first new insert, the next time I call insertOrUpdate method, search method returns true. And updateData method was called and it also returns true.
-search, cursor.getCount() = also prints 1.
But when I check the contents of the table, there are two rows with same MY_ID value and different MY_ANOTHER_ID values.
What am I missing?
Lot's of things can go wrong here.
Non atomic operations.
You are first querying whether an object exists then doing the insert or update. In android it's unlikely that another thread will create another object in between these two operations but in other places it can happen so this is a habit to avoid.
Unique key on MY_ID, MY_ANOTHER_ID
If there can only be one MY_ID in that table you should have a unique key on it. If not you should have a together unique key on the my_id, my_another_id pair of columns.
Code in search method.
if (null != cursor && cursor.getCount() == 1
&& cursor.moveToFirst()) {
return true
}
This will return true if there is exactly one record for my_id what if you have two? Then this method will not return true, the calling function will believe there aren't any matching records in that table.
Insert or Update the real deal
Android Sqlite supports ON CONFLICT REPLACE. You can simplify your code a great deal by making use of it.
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).
/**
* Updates the data at the given selection and selection arguments, with the new ContentValues.
*/
#Override
public int update(Uri uri, ContentValues contentValues, String selection,
String[] selectionArgs) {
final int match = sUriMatcher.match(uri);
switch (match) {
case TASKS:
return updatetask(uri, contentValues, selection, selectionArgs);
case TASKS_ID:
// For the task_ID code, extract out the ID from the URI,
// so we know which row to update. Selection will be "_id=?" and selection
// arguments will be a String array containing the actual ID.
selection = TaskContract.TaskEntry._ID + "=?";
selectionArgs = new String[]{String.valueOf(ContentUris.parseId(uri))};
return updatetask(uri, contentValues, selection, selectionArgs);
default:
throw new IllegalArgumentException("Update is not supported for " + uri);
}
}
/**
* Update tasks in the database with the given content values. Apply the changes to the rows
* specified in the selection and selection arguments (which could be 0 or 1 or more tasks).
* Return the number of rows that were successfully updated.
*/
private int updatetask(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
// If the {#link TaskEntry#COLUMN_task_NAME} key is present,
// check that the name value is not null.
if (values.containsKey(TaskContract.TaskEntry.COLUMN_TASK_NAME)) {
String name = values.getAsString(TaskContract.TaskEntry.COLUMN_TASK_NAME);
if (name == null) {
throw new IllegalArgumentException("task requires a name");
}
}
// If the {#link TaskEntry#COLUMN_task_GENDER} key is present,
// check that the gender value is valid.
if (values.containsKey(TaskContract.TaskEntry.COLUMN_TASK_DATE)) {
String date = values.getAsString(TaskContract.TaskEntry.COLUMN_TASK_DATE);
if (date == null) {
throw new IllegalArgumentException("Enter valid date.");
}
}
// If the {#link TaskEntry#COLUMN_task_WEIGHT} key is present,
// check that the weight value is valid.
if (values.containsKey(TaskContract.TaskEntry.COLUMN_TASK_TIME)) {
// Check that the weight is greater than or equal to 0 kg
String time = values.getAsString(TaskContract.TaskEntry.COLUMN_TASK_TIME);
if (time == null) {
throw new IllegalArgumentException("task requires valid time ");
}
}
// If there are no values to update, then don't try to update the database
if (values.size() == 0) {
return 0;
}
// Otherwise, get writeable database to update the data
SQLiteDatabase database = mDbHelper.getWritableDatabase();
// Perform the update on the database and get the number of rows affected
int rowsUpdated = database.update(TaskContract.TaskEntry.TABLE_NAME, values, selection, selectionArgs);
if (rowsUpdated != 0) {
getContext().getContentResolver().notifyChange(uri, null);
}
return rowsUpdated;
}
Above is the code for my content provider update method.
/**
* Get user input from editor and save new task into database.
*/
private void saveTask() {
// Read from input fields
// Use trim to eliminate leading or trailing white space
String nameString = mNameEditText.getText().toString().trim();
String dateString = mDateEditText.getText().toString().trim();
String timeString = mTimeEditText.getText().toString().trim();
String locationString = mLocationEditText.getText().toString().trim();
if (mNotifySwitch.isChecked()){
mToNotify = TaskContract.TaskEntry.NOTIFY_YES;
}
if (mCurrenttaskUri == null &&
TextUtils.isEmpty(nameString) && TextUtils.isEmpty(dateString) &&
TextUtils.isEmpty(timeString) && TextUtils.isEmpty(locationString)) {
return;
}
// Create a ContentValues object where column names are the keys,
// and task attributes from the editor are the values.
ContentValues values = new ContentValues();
values.put(TaskContract.TaskEntry.COLUMN_TASK_NAME, nameString);
values.put(TaskContract.TaskEntry.COLUMN_TASK_DATE, dateString);
values.put(TaskContract.TaskEntry.COLUMN_TASK_TIME, timeString);
String location = null;
if (!TextUtils.isEmpty(locationString)) {
location = locationString;
}
values.put(TaskContract.TaskEntry.COLUMN_TASK_LOCATION, location);
values.put(TaskContract.TaskEntry.NOTIFY_LOCATION, mToNotify);
// Insert a new row for task in the database, returning the ID of that new row.
// long newRowId = db.insert(TaskContract.TaskEntry.TABLE_NAME, null, values);
if (mCurrenttaskUri == null) {
Uri newUri = getContentResolver().insert(TaskContract.TaskEntry.CONTENT_URI, values);
if (newUri == null) {
// If the new content URI is null, then there was an error with insertion.
Toast.makeText(this, "Inserting task failed!",
Toast.LENGTH_SHORT).show();
} else {
// Otherwise, the insertion was successful and we can display a toast.
Toast.makeText(this, "Inserting task successful!",
Toast.LENGTH_SHORT).show();
}
} else {
int rowsAffected = getContentResolver().update(TaskContract.TaskEntry.CONTENT_URI, values, null, null);
if (rowsAffected == 0) {
Toast.makeText(this, "Updating task failed!",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Updating task successful!.",
Toast.LENGTH_SHORT).show();
}
}
}
Now, above is the code for providing content values.
Querying and Inserting are working properly, but, when I update one row in my app, all the rows gets filled up with the same updated data.
Please help..
Below is the code for table creation.
#Override
public void onCreate(SQLiteDatabase db) {
// Create a String that contains the SQL statement to create the tasks table
String SQL_CREATE_TASKS_TABLE = "CREATE TABLE " + TaskContract.TaskEntry.TABLE_NAME + " ("
+ TaskContract.TaskEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ TaskContract.TaskEntry.COLUMN_TASK_NAME + " TEXT NOT NULL, "
+ TaskContract.TaskEntry.COLUMN_TASK_DATE + " TEXT NOT NULL, "
+ TaskContract.TaskEntry.COLUMN_TASK_TIME + " TEXT NOT NULL, "
+ TaskContract.TaskEntry.COLUMN_TASK_LOCATION + " TEXT, "
+ TaskContract.TaskEntry.NOTIFY_LOCATION + " INTEGER NOT NULL);";
// Execute the SQL statement
db.execSQL(SQL_CREATE_TASKS_TABLE);
}
Need immediate help, please respond
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;
}
I'm running an update query that compiles. But when I test the results, there seem to be no changes. Everything looks good to me, but clearly something is wrong. Can anyone see what I am missing. Pretty new to SQLite, so apologies if it's something simple. Thanks!
public static Boolean updateHealth (int unitVal, int oldValue, int newValue) {
String unit = Integer.toString(unitVal);
String oldVal = Integer.toString(oldValue);
String newVal = Integer.toString(newValue);
System.err.printf("old val: %s, new val: %s\n", oldVal, newVal);
SQLiteDatabase db = myDBOpenHelper.getWritableDatabase();
String where = UNIT_COLUMN + " = " + unit + " AND " + HEALTH_COLUMN + " = " + oldVal;
Cursor cursor = db.query(UNITS_TABLE, new String[] {UNIT_COLUMN}, where, null, null, null, null);
if (cursor != null) {
/* the record doesn't exist, cancel the operation */
return false;
}
ContentValues updatedValues = new ContentValues();
updatedValues.put(HEALTH_COLUMN, newVal);
/* SQL query clauses */
String whereArgs[] = null;
db.update(UNITS_TABLE, updatedValues, where, whereArgs);
return true;
}
The cursor is not null when no row is retrieved. So you have to replace the line if (cursor != null) { by if(!cursor.moveToNext()) {
By the way, you don't need to query the database before updating. You can do the update, see how many rows have been affected and return true if the number of affected rows is > 0, false otherwise. The number of affected rows is returned by the method update.
Is there a nice way in Android to see if a column exists in a table in the application database? (I know there are questions similar to this one already, but there don't seem to be any that are Android specific.)
cursor.getColumnIndex(String columnName) returns -1 if, the column doesn't exist. So I would basically perform a simple query like "SELECT * FROM xxx LIMIT 0,1" and use the cursor to determine if the column, you are looking for, exists
OR
you can try to query the column "SELECT theCol FROM xxx" and catch an exception
My function based on #martinpelants answer:
private boolean existsColumnInTable(SQLiteDatabase inDatabase, String inTable, String columnToCheck) {
Cursor mCursor = null;
try {
// Query 1 row
mCursor = inDatabase.rawQuery("SELECT * FROM " + inTable + " LIMIT 0", null);
// getColumnIndex() gives us the index (0 to ...) of the column - otherwise we get a -1
if (mCursor.getColumnIndex(columnToCheck) != -1)
return true;
else
return false;
} catch (Exception Exp) {
// Something went wrong. Missing the database? The table?
Log.d("... - existsColumnInTable", "When checking whether a column exists in the table, an error occurred: " + Exp.getMessage());
return false;
} finally {
if (mCursor != null) mCursor.close();
}
}
Simply call:
boolean bla = existsColumnInTable(myDB,"MyTable","myColumn2check");
I actually wrote this function that seems pretty clean:
private boolean field_exists( String p_query )
{
Cursor mCursor = mDb.rawQuery( p_query, null );
if ( ( mCursor != null ) && ( mCursor.moveToFirst()) )
{
mCursor.close();
return true ;
}
mCursor.close();
return false ;
}
I call it like this:
if ( field_exists( "select * from sqlite_master "
+ "where name = 'mytable' and sql like '%myfield%' " ))
{
do_something ;
}
Here is my solution to the issue which adds to flexo's solution a little.
You can put this method in any class, perhaps your SQLiteOpenHelper extending class.
public static boolean columnExistsInTable(SQLiteDatabase db, String table, String columnToCheck) {
Cursor cursor = null;
try {
//query a row. don't acquire db lock
cursor = db.rawQuery("SELECT * FROM " + table + " LIMIT 0", null);
// getColumnIndex() will return the index of the column
//in the table if it exists, otherwise it will return -1
if (cursor.getColumnIndex(columnToCheck) != -1) {
//great, the column exists
return true;
}else {
//sorry, the column does not exist
return false;
}
} catch (SQLiteException Exp) {
//Something went wrong with SQLite.
//If the table exists and your query was good,
//the problem is likely that the column doesn't exist in the table.
return false;
} finally {
//close the db if you no longer need it
if (db != null) db.close();
//close the cursor
if (cursor != null) cursor.close();
}
}
If you use ActiveAndroid
public static boolean createIfNeedColumn(Class<? extends Model> type, String column) {
boolean isFound = false;
TableInfo tableInfo = new TableInfo(type);
Collection<Field> columns = tableInfo.getFields();
for (Field f : columns) {
if (column.equals(f.getName())) {
isFound = true;
break;
}
}
if (!isFound) {
ActiveAndroid.execSQL("ALTER TABLE " + tableInfo.getTableName() + " ADD COLUMN " + column + " TEXT;");
}
return isFound;
}
At the risk of just posting the same solution but shorter. Here's a cut down version based on #flexo's
private boolean doesColumnExistInTable(SupportSQLiteDatabase db, String tableName, String columnToCheck) {
try (Cursor cursor = db.query("SELECT * FROM " + tableName + " LIMIT 0", null)) {
return cursor.getColumnIndex(columnToCheck) != -1;
} catch (Exception Exp) {
// Something went wrong. we'll assume false it doesn't exist
return false;
}
}
And in Kotlin
private fun doesColumnExistInTable(db: SupportSQLiteDatabase, tableName: String, columnToCheck: String): Boolean {
try {
db.query("SELECT * FROM $tableName LIMIT 0", null).use { cursor -> return cursor.getColumnIndex(columnToCheck) != -1 }
} catch (e: Exception) {
// Something went wrong. we'll assume false it doesn't exist
return false
}
}
this is my testing code:
String neadle = "id"; //searched field name
String tableName = "TableName";
boolean found = false;
SQLiteDatabase mDb = ActiveAndroid.getDatabase();
Cursor mCursor = mDb.rawQuery( "SELECT * FROM sqlite_master WHERE name = '"+tableName+"' and sql like '%"+neadle+"%'" , null);
mCursor.moveToFirst();
String fie = ",";
if (mCursor.getCount() > 0) {
String[] fields = mCursor.getString(mCursor.getColumnIndex("sql")).split(",");
for (String field: fields) {
String[] fieldNameType = field.trim().split(" ");
if (fieldNameType.length > 0){
fie += fieldNameType[0]+",";
}
}
}else {
//table not exist!
}
if (mCursor != null) mCursor.close();
// return result:
found = fie.contains(","+neadle+",");