Android SQLite Transaction - android

I am trying to insert into two tables within one transaction, the insert works as when i do it it return the id of the new row for both tables but it look like it is not being committed to the tables
db.beginTransactionWithListenerNonExclusive(this);
try{
db.insertWithOnConflict(TABLE_NAME1, null, values, SQLiteDatabase.CONFLICT_ROLLBACK);
db.insertWithOnConflict(TABLE_NAME2, null, values, SQLiteDatabase.CONFLICT_ROLLBACK);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
db.close();
}
clarification, only when inserting to more than one table it doesn't work, when inserting to one table it work.
note: I checked if the insert operations were successful and they were, but committing the rows to the tables is what fails

end and begin transaction after each table, issue can be solved

Related

Update/replace row if same ID already exists

I have the below method which inserts values in my sqlite db. I'm trying to update the code to handle situations where "carid" and "sellerno" already exist in the table and if they do to replace with the new values being inserted. Any help is appreciated.
public void addListItem(String carid,String sellerno,String condition,String dat) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(carid, carid);
values.put(sellerno, sellerno);
values.put(cond, condition);
values.put(updatetime, dat);
db.insert(TABLE_CARS, null, values);
db.close();
}
There are two requirements:
SQLite needs to know that the combination of carid and sellerno must be unique for all rows in the table.
SQLite needs to know what to do when an insert or update results in a conflict (more than one row with the same combination of values for those columns).
You can do both of these at once by modifying your CREATE TABLE command as follows:
CREATE TABLE tableName (
column1 ...,
column2 ...,
...,
UNIQUE(column1, column2) ON CONFLICT REPLACE)
Now any insert/update will automatically replace the values in existing rows when the insert/update would create a conflict.
However, there may be situations where you do NOT want to replace the values in the row when there is a conflict. In those cases, you should specify the conflict algorithm in the insert/update itself (using this or this), which will override the replace algorithm specified above. Alternatively, you can leave off the ON CONFLICT REPLACE above and just use regular inserts/updates, but then you must insert/update with conflict when you want to replace.
You can read more about conflict algorithms here.
The update code is very similar to what you have now.
You have to add the new values but the same ids that you want, and then instead of the method insert(...) you use replace(...) or update(...).
db.update(TABLE_CARS, values, "_id "+"="+1, null);
// The third argument above is the where clause.
The other way would be:
db.replace(TABLE_CARS, null, values);
The rest of your code is the same. Just change the insert line.

Android SQLite Alter table rename not commit

Thanks in advance.
I need to reestructure my database in the new version of my app, and then I use onUpgrade method in my SQLiteOpenHelper class for this purpose.
Well, I need to rename some columns, and how it is not possible in sqlite I decided to create another table, import all data and then delete the old table and rename de new table. All in "onUpgrade" method... well, at the end of the method I need to upload the database to a server, when I walk thought tables I found that cursor returns nullpointer because it not found the new fields, but in fact when I go to de file explorer in DDMS and view the database from my phone I see that fields are inside.
It seems that changes not commit, but I use databasetransaction for this purpose.
What I do wrong?
My code in onupgrade seems like that:
public void onUpgrade(final SQLiteDatabase db, int oldVersion, int newVersion) {
if(oldVersion==22 && newVersion==23){
try {
db.beginTransaction();
db.execSQL("CREATE TABLE unidades2 (uuid text, nombre TEXT)");
c=db.rawQuery("SELECT * FROM unidades",null);
c.moveToFirst();
while(!c.isAfterLast()){
auxuuid=new uuid().toString();
db.execSQL("INSERT INTO unidades2(uuid, nombre) VALUES (?,?)",new String[] {auxuuid,c.getString(1)});
c.moveToNext();
}
c.close();
db.execSQL("DROP TABLE unidades");
db.execSQL("ALTER TABLE unidades2 RENAME TO unidades");
db.setTransactionSuccessful();
}
finally db.endTransaction();
}
}
And then walking through unidades table whith a cursor, and do:
try {
db.beginTransaction();
Cursor cursor = db.rawQuery("SELECT * FROM unidades",null);
cursor.moveToFirst();
int hasuuid= cursor.getColumnIndex("uuid");
cursor.close();
[Code uploading database in JSON]
db.setTransactionSuccessful();
}
finally db.endTransaction();
hasuuid its -1.
Please help me!! Thanks a lot.
One issue that might cause the problem though it's not apparent in the snippets you posted: onUpgrade() is already run inside a transaction. sqlite itself does not support nested transactions. The Android wrapper on top adds partial support so that nested transactions are only committed or rolled back once the outermost transaction is committed or rolled back. The outermost transaction in this case being the one set up before onUpgrade() was called. So when you think you commit, no actual commit is performed on sqlite database level.

SQLiteDatabase insert or replace if changed

I'm looking for a way to fill/update my SQLiteDatabase table.
On some occasions I need to be notified (by certain return value). Each row contains a url of a file that needs to be downloaded later.
row does not exist yet: insert it and notify me that this row should be listed for download.
row does exist but the one I'm trying to insert contains the same values as the one already in the db: do nothing, do not notify me that this should be downloaded.
row does exist and the one I'm trying to insert contains different values as the one already in the db: replace this row, notify me that this should be downloaded.
I've been looking for the answer but can't seem to find something good. Should I use insertWithOnConflict(), replace(), replaceOrThrow(), ...
Thanks!
Do it in two steps wrapped in a single sqlite transaction:
Query by rowid. If no rowid or or no result found, insert new and download.
Compare url of new row and row retrieved in step 1. Only if the urls are different, update the row and download, otherwise no-op.
First, you query if value exist in DB with cursor & if it's null you make an insert otherwise you make an update if the required field is different from what you have already.
In any other case do nothing
// Some pseudocode
Cursor cursor=_db.query("TABLE", null, TABLEID + "=?", new String[]{id}, null, null, null);
if(cursor.getCount()<1) // row Not Exist
{
cursor.close();
....assign values
SQLiteDatabase _db.insert("TABLE_Name", null, Table_object);
download ...ok
}
cursor.moveToFirst();
if( cursor[field] != "same_value" ) {
SQLiteDatabase _db.update("TABLE_Name", null, Table_object);
download ...ok
}

SQLiteDatabase transaction doesn't add data

I have to execute a bunch of SQL rows in order to put some data into my tables. There's a lot of those rows (around 15 MB of raw SQL instructions), so I tried to use transactions in order to improve database performance. That's my code:
SQLiteDatabase db;
...
db.beginTransaction();
...
//in cycle:
db.execSQL(row);
...
db.endTransaction();
db.close();
But when I launch my app, I can see in logs that SQL scripts are executing, but there's no data in DB. And if I simply remove db.beginTransaction(); and db.endTransaction(); - everything works fine. Any ideas how I have to work with transactions?
db.beginTransaction();
try {
//in cycle:
db.execSQL(row);
db.setTransactionSuccessful();
}catch {
}finally {
db.endTransaction();
}
public void setTransactionSuccessful ()
Added in API level 1 Marks the current transaction as successful. Do
not do any more database work between calling this and calling
endTransaction. Do as little non-database work as possible in that
situation too. If any errors are encountered between this and
endTransaction the transaction will still be committed.

How to insert data into two tables at once using SQLiteDatabase in Android?

So lets say I have this code:
SQLiteDatabase sqlDB = database.getWritableDatabase();
long iD = 0;
iD = sqlDB.insert(Table1, null, TestV);
Can I somehow rewrite this to insert into two tables instead of one? My problem is that 'values' returns 3 values from one table, and 1 value from another. Therefore, the 1 value that isn't in 'Table1' sets off an error that the column cant be found in 'Table1.' Is there a way to do this? If not then should I do two separate inserts? I am confused as how to insert data into two tables in one database (Tables are Relational: one has a foreign key).
From the documentation for INSERT in SQLite:
Note that the flowchart doesn't give you an opportunity to post into more than one table at once. SQLiteDatabase.insert() is a convenience method for using the INSERT statement.
You can simulate this using database transaction:
SQLiteDatabase db = getWritableDatabase();
db.beginTransaction();
try {
db.execSQL("insert into table1...");
db.execSQL("insert into table2...");
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
You may need to choose the order of the inserts if there are dependencies between the values inserted, for instance if there's a foreign key relationship: ( insert to table1 and then table2, or first insert to table2...)

Categories

Resources