I am trying to delete all rows in an SQLite Database where the Id = null
Here is my code :-
public void deleteNullSongs() {
SQLiteDatabase db = this.getReadableDatabase();
String sql = String.format("ID=%s", null);
db.delete(TABLE_NAME, sql, null);
}
But it does not delete any vlues can't work out what is wrong ?
I have tried different ways of doing this but when i print the contents of the database the rows are still there
You should use IS NULL in your where clause:
db.delete(TABLE_NAME, "ID IS NULL", null);
I have an android app that needs to check if there's already a record in the database, and if not, process some things and eventually insert it, and simply read the data from the database if the data does exist. I'm using a subclass of SQLiteOpenHelper to create and get a rewritable instance of SQLiteDatabase, which I thought automatically took care of creating the table if it didn't already exist (since the code to do that is in the onCreate(...) method).
However, when the table does NOT yet exist, and the first method ran upon the SQLiteDatabase object I have is a call to query(...), my logcat shows an error of "I/Database(26434): sqlite returned: error code = 1, msg = no such table: appdata", and sure enough, the appdata table isn't being created.
Any ideas on why?
I'm looking for either a method to test if the table exists (because if it doesn't, the data's certainly not in it, and I don't need to read it until I write to it, which seems to create the table properly), or a way to make sure that it gets created, and is just empty, in time for that first call to query(...)
EDIT
This was posted after the two answers below:
I think I may have found the problem. I for some reason decided that a different SQLiteOpenHelper was supposed to be created for each table, even though both access the same database file. I think refactoring that code to only use one OpenHelper, and creating both tables inside it's onCreate may work better...
Try this one:
public boolean isTableExists(String tableName, boolean openDb) {
if(openDb) {
if(mDatabase == null || !mDatabase.isOpen()) {
mDatabase = getReadableDatabase();
}
if(!mDatabase.isReadOnly()) {
mDatabase.close();
mDatabase = getReadableDatabase();
}
}
String query = "select DISTINCT tbl_name from sqlite_master where tbl_name = '"+tableName+"'";
try (Cursor cursor = mDatabase.rawQuery(query, null)) {
if(cursor!=null) {
if(cursor.getCount()>0) {
return true;
}
}
return false;
}
}
I know nothing about the Android SQLite API, but if you're able to talk to it in SQL directly, you can do this:
create table if not exists mytable (col1 type, col2 type);
Which will ensure that the table is always created and not throw any errors if it already existed.
Although there are already a lot of good answers to this question, I came up with another solution that I think is more simple. Surround your query with a try block and the following catch:
catch (SQLiteException e){
if (e.getMessage().contains("no such table")){
Log.e(TAG, "Creating table " + TABLE_NAME + "because it doesn't exist!" );
// create table
// re-run query, etc.
}
}
It worked for me!
This is what I did:
/* open database, if doesn't exist, create it */
SQLiteDatabase mDatabase = openOrCreateDatabase("exampleDb.db", SQLiteDatabase.CREATE_IF_NECESSARY,null);
Cursor c = null;
boolean tableExists = false;
/* get cursor on it */
try
{
c = mDatabase.query("tbl_example", null,
null, null, null, null, null);
tableExists = true;
}
catch (Exception e) {
/* fail */
Log.d(TAG, tblNameIn+" doesn't exist :(((");
}
return tableExists;
Yep, turns out the theory in my edit was right: the problem that was causing the onCreate method not to run, was the fact that SQLiteOpenHelper objects should refer to databases, and not have a separate one for each table. Packing both tables into one SQLiteOpenHelper solved the problem.
// #param db, readable database from SQLiteOpenHelper
public boolean doesTableExist(SQLiteDatabase db, String tableName) {
Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null);
if (cursor != null) {
if (cursor.getCount() > 0) {
cursor.close();
return true;
}
cursor.close();
}
return false;
}
sqlite maintains sqlite_master table containing information of all tables and indexes in database.
So here we are simply running SELECT command on it, we'll get cursor having count 1 if table exists.
You mentioned that you've created an class that extends SQLiteOpenHelper and implemented the onCreate method. Are you making sure that you're performing all your database acquire calls with that class? You should only be getting SQLiteDatabase objects via the SQLiteOpenHelper#getWritableDatabase and getReadableDatabase otherwise the onCreate method will not be called when necessary. If you are doing that already check and see if th SQLiteOpenHelper#onUpgrade method is being called instead. If so, then the database version number was changed at some point in time but the table was never created properly when that happened.
As an aside, you can force the recreation of the database by making sure all connections to it are closed and calling Context#deleteDatabase and then using the SQLiteOpenHelper to give you a new db object.
Kotlin solution, based on what others wrote here:
fun isTableExists(database: SQLiteDatabase, tableName: String): Boolean {
database.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '$tableName'", null)?.use {
return it.count > 0
} ?: return false
}
public boolean isTableExists(String tableName) {
boolean isExist = false;
Cursor cursor = db.rawQuery("select DISTINCT tbl_name from sqlite_master where tbl_name = '" + tableName + "'", null);
if (cursor != null) {
if (cursor.getCount() > 0) {
isExist = true;
}
cursor.close();
}
return isExist;
}
no such table exists: error is coming because once you create database with one table after that whenever you create table in same database it gives this error.
To solve this error you must have to create new database and inside the onCreate() method you can create multiple table in same database.
Important condition is IF NOT EXISTS to check table is already exist or not in database
like...
String query = "CREATE TABLE IF NOT EXISTS " + TABLE_PLAYER_PHOTO + "("
+ KEY_PLAYER_ID + " TEXT,"
+ KEY_PLAYER_IMAGE + " TEXT)";
db.execSQL(query);
i faced that and deal with it by try catch as simple as that i do what i want in table if it not exist will cause error so catch it by exceptions and create it :)
SQLiteDatabase db=this.getWritableDatabase();
try{
db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations");
db.execSQL("DELETE FROM vacations");
}catch (SQLiteException e){
db.execSQL("create table o_vacations (id integer primary key ,name text ,vacation text,date text,MONTH text)");
db.execSQL("INSERT INTO o_vacations SELECT * FROM vacations");
db.execSQL("DELETE FROM vacations");
}
.....
Toast t = Toast.makeText(context, "try... " , Toast.LENGTH_SHORT);
t.show();
Cursor callInitCheck = db.rawQuery("select count(*) from call", null);
Toast t2a = Toast.makeText(context, "count rows " + callInitCheck.getCount() , Toast.LENGTH_SHORT);
t2a.show();
callInitCheck.moveToNext();
if( Integer.parseInt( callInitCheck.getString(0)) == 0) // if no rows then do
{
// if empty then insert into call
.....
I have the following insert statement in my app which work.
Before the insert I want to first check the database if the value name does not exist in the name column.
If it does not exists I want to continue with the insert, else display an error message.
How do I incorporate it into my existing statement below?
public void insert(HashMap<String, String> queryValues){
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
Cursor c = database.query("SELECT * FROM user_details where" + "name=?", new String[] {values.put("name") });
if (c.getCount() > 0) {
// don't do it
return;
}
else {
values.put("name", queryValues.get("name"));
values.put("age", queryValues.get("age"));
database.insert("user", null, values);
}
database.close();
}
The correct way to do this is to add a unique constraint on the name field, and then use insertWithOnConflict() with a last argument of CONFLICT_FAIL. That's actually the default behavior. Your insert will fail if it would otherwise cause a constraint violation (insert() will return -1).
If you don't want to do that, there's no magic. Query your DB for a row with the given name field. If you are returned >0 rows, don't perform the insert.
Cursor c = db.query(..., "name=?", new String[] {theName}, ...);
if (c.getCount > 0) {
// don't do it
return;
}
Inserting data to SQLite table with constraint failure
I'm trying to insert data into SQLite table on Android. _id is primary key of the table and I am inserting a row using this method:
public void addSomeData(int id, String datetime) {
ContentValues contentValues = new ContentValues();
contentValues.put(KEY_ID, id);
contentValues.put(KEY_DATETIME, datetime);
mDb.insert(TABLE, null, contentValues);
}
The problem I get is that sometimes primary key constraint is validated and I would like to use something like INSERT IF NOT EXISTS, but preferably something that would work with ContentValues. What are my options? I understand that insertOrThrow() and insertWithOnConflict() methods only return different values, or should I use one of these methods?
Use insertWithOnConflict() with CONFLICT_IGNORE.
Will return ROWID/primary key of new or existing row, -1 on any error.
In my case "constraint failure" happened because of I had some tables which are depended on each other. As for the "insert if not exist", you can query with this id and you check if the cursor's count is bigger than zero. Check the method I'm already using in my app.
public boolean isRowExists(long rowId) {
Cursor cursor = database.query(this.tableName, this.columns, DBSQLiteHelper.COLUMN_ID + " = ? ", new String[] { "" + rowId }, null, null, null);
int numOfRows = cursor.getCount();
cursor.close();
return (numOfRows > 0) ? true : false;
}
to do so you could simply query the db to see if a row with that key exists and insert the new row only if the query returns no data.
I want to insert data successfully
Here is my code:
public void insertData(String strTableName,
ArrayList<HashMap<String, String>> arrListproductdatabase) {
db = this.getWritableDatabase();
ContentValues cv = new ContentValues();
for (int i = 0; i < arrListproductdatabase.size(); i++) {
// cv.put(columnName, arrListOfRecord.get(i).get("name"));
cv.put(columnproductname,
arrListproductdatabase.get(i).get("product"));
cv.put(columnproductprice,
arrListproductdatabase.get(i).get("price"));
cv.put(columnproductquantity,
arrListproductdatabase.get(i).get("quantity"));
cv.put(columnproductid,
arrListproductdatabase.get(i).get("productID"));
cv.put(columnresturantID,
arrListproductdatabase.get(i).get("resturantID"));
db.insert(strTableName, null, cv);
}
I want that when I have to press add button again, that time it should check if the product is already inserted, and in that condition it should update and all.
I don't want to create any duplicate value.
Any help would be appreciated!
you can check for the distinct values in the db. please follow the link to have more details
android check duplicate values before inserting data into database
Set 'Product' field as unique key. So when duplicate value arrives from standard insert, it will simply return -1 and the error message will be swallowed.
You can control the behavior by using insertWithOnConflict (String table, String nullColumnHack, ContentValues initialValues, int conflictAlgorithm) where you also specify a conflict algorithm that can be of values:
CONFLICT_ABORT
CONFLICT_FAIL
CONFLICT_IGNORE
CONFLICT_REPLACE
CONFLICT_ROLLBACK
Check out the reference for descrption of the conflict resolution types.
There is also an updateWithOnConflict
You can do that like this :
public boolean checkProduct(String product){
// shold open database here
Cursor mCursor =
db.query(true, DATABASE_TABLE, null, "product='" + product+"'", null, null, null, null, null);
if(mCursor != null){
mCursor.close();
// shold close database here
return true;
}
// shold close database first here also
return false;
}
Hope this helped you.