So, the issue is simple. I am updating into a table, and the primary key is autoincrementing... This means that all related tables are screwed over. I am using sqlite, so I don't think there is any inherent mechanism that can catch this and related tables.
Due to a lack of support for foreign keys in the sqlite versions I must work with, I force the relations by adding the primary key returned from an insert into the parent table into the related tables when entering new data.
Is there an alternative to updating all related tables each time I do an update? Please say yes..
Edit: last edit was wrong, I got confused. I have simply pasted the code governing inserts/replacements below. I am replacing into, not updating into, typing error on my part.
//inserts
public long insertIntoCompany(String company, int subs) {
ContentValues cv = new ContentValues();
cv.put(company_column, company);
cv.put(company_subscribed_column, subs);
return db.replace(company_table, null, cv);
}
You should actually be using the SQL update query. See this answer.
If you paste your query we might be able to offer more help.
Related
For an android room interface, I want to get the autogenerated id (as primary key of a record just inserted), so that I can put it in the object without executing a select after insert, where the select might return the wrong record if there is no other unique attribute, or set of attributes for those record types.
For example, for 2 people having the same name being inserted into the same table. You might say generate a composite key to make a unique set. However that might involve the addition of new fields that are otherwise not required.
I've seen various links, including those below. Some mention that it is the row id that is returned if the insert method is declared to return integer (or long), and succeeds.
However it is my understanding that the row id cannot be assumed to be the same as the primary key. (Refer Rowid after Insert in Room).
I cannot comment on any posts because I don't have enough reputation points.
I appreciate any comments regarding what might be a good/typical approach to this problem.
These are the posts I have looked upon:
Android Room - Get the id of new inserted row with auto-generate
https://developer.android.com/training/data-storage/room/accessing-data
https://commonsware.com/AndroidArch/previews/the-dao-of-entities
Late answer just for anyone seeing this question in the future
from SQLite docs it says :
The PRIMARY KEY of a rowid table (if there is one) is usually not the
true primary key for the table, in the sense that it is not the unique
key used by the underlying B-tree storage engine. The exception to
this rule is when the rowid table declares an INTEGER PRIMARY KEY. In
the exception, the INTEGER PRIMARY KEY becomes an alias for the rowid.
therefore it's correct to assume that the rowId returned by insert query is the same as the autoincremented-primary-key
I have a simple database schema containing 5 tables and a few foreign key relationships. Now I want to update the schema without losing the relationships.
SQLite does not support the operation I want to perform. I want to mark a column AUTOINCREMENT. So I searched and found that I need to recreate the tables.
In all the relationships, foreign key is the auto-generated row ID. This will change when I re-insert the data (right?). And the best case scenario would be having mismatched relationships. The worst case (I think) would be having foreign keys that correspond to nothing. How do I avoid this?
One way that I can think of doing this is through dumping all data into a special model designed for this very exercise. This special model will encapsulate all the relationships. Then I can start creating new tables in order of ascending dependence, from least to most. Table that has no foreign keys (but other tables use its ID) goes in first. And on inserting rows, I update the model instance.
Is there a better way of doing this? Thank you for reading.
Values in an autoincrementing column can be set to an explicit value:
INSERT INTO MyTable(MyAutoincID, Name) VALUES(42, 'hello')
Just copy the ID together with the other column values.
Furthermore, as long as you do not enable foreign key checking with PRAGMA foreign_keys or setForeignKeyConstraintsEnabled(), your DB is allowed to have inconsistent data temporarily.
I have an already functioning app running on iOS whose database uses a composite primary key. For discussions sake, lets say "CID" and "RID" make up that composite pk, resulting in something that looks like:
CID-RID
F6uuDTEU1c-1
F6uuDTEU1c-2
F6uuDTEU1c-3
However, there are conditions under which the CID column is altered, resetting the RID column. For example:
CID-RID
...
F6uuDTEU1c-4
F6uuDTEU1c-5
WQq6JnyrDI-1
WQq6JnyrDI-2
WQq6JnyrDI-3
...etc
These databases are to be shared cross-platform (ios - android) and going back and editing the current ios structure is not an option. What issues am I going to run into not having an _id column as my pk running on Android?
I found this here on SO - which seems to state that the db itself does not have to have the _id column, only that ...
"The result set for the cursor must contain _id, not the cursor itself."
... but I could be reading this all wrong. Any input/help is much appreciated.
PS: I already looked at a few (what I thought were) similar questions here, here, and here.
You are free to have any database schema you want. Android doesn't impose any additional restrictrions there.
Only if you use a CursorAdapter, then the Cursor needs an _id column. Any app can be written without using CursorAdapter, it's just there to provide some convenience. sqlite tables always have a ROWID column that aliases to the INTEGER PRIMARY KEY column if the table has one. You can always select it as the _id, e.g. SELECT rowid AS _id ... if needed.
Firstly I want to say, I really liked Stackmob.
But I've got some little problems because I'm a newbie on stackmob.
I'm developing on Android sdk
I have created a schema called "level" and it has 2 unique indexes (facebook_id and level_no)
My question is how to insert, update and delete (crud) the rows by facebook_id and level_no.
(ps: I can update a schema if it has 1 unique index but when index counts are greater than 1, I dont know how to do it.)
An index isn't like a primary key; it doesn't enforce uniqueness, it just speeds up querying on those fields. You still have to think in terms of level_id as your primary key. It's not hard to do CRUD operations in terms of other fields though. For insert, if you leave out the primary key, one will be generated for you. For the other operations, you can query by the field you want:
Level.query(Level.class, new StackMobQuery().fieldIsEqualTo("facebook_id", "foo"), new StackMobQueryCallback<Level>() {...});
then once you've got your Level object, simply resave or delete
myLevel.setSomething("bar");
myLevel.save();
// or
myLevel.delete();
If you're using the datastore api, it's the same idea, you're just making the REST API calls directly.
i am getting information from user in sqlite database.
But when i insert same record which is already in database it is added again.
how i can stop duplication of record in sqlite. I am developing this in android.
I am using mobile number as primary key. still it add that record in database.
Please suggest me appropriate solutions.
Thanks in advanced.
Be aware of the limitations of REPLACE or INSERT OR REPLACE as these will overwrite any custom data your app user has added to these rows in the database - it is not as advanced as UPSERT in other SQL databases.
As mentioned in a previous post you really need to identify what the primary key could be and use this information to either update old data or to remove an old row before inserting the fresh one.
If this is not possible then you could always DELETE FROM my_table or DROP my_table before running the insertions so that there will be no duplicates. This will (for better or worse) also make sure that data that is missing from new imports is not left lying around in your app.
make sure you have set your phone number as Primary Key at the time you created the table.
for example:
String query = "CREATE TABLE IF NOT EXISTS PhoneBook ("+
"TelNum VARCHAR(100) PRIMARY KEY NOT NULL,"+
"Address TEXT);";
db.execSQL(query);
and in case you want to enforce foreign keys defined in your table then call the following method before doing anything in your database
db.execSQL("PRAGMA foreign_keys = ON;"); //enforcing FK
Use REPLACE INTO keyword:
REPLACE INTO my_table (pk_id, col1) VALUES (5, '123');
This automatically identifies the primary key and finds a matching row to update, inserting a new one if none is found.