how we can delete foreign-key in sqlite? - android

I am working with an SQLite database. I have a table which contain the primary keys of 2 other tables as foreign keys; I want to delete one of them. Here is the code for the table:
protected static final String Item_places=(" CREATE TABLE "
+ Item_place + "("
+ place_id + " INTEGER ,"
+ Item_id + " INTEGER ,"
+ "FOREIGN KEY("+place_id+ ") REFERENCES " + PlaceTable + "("+ PlaceID+ " ) ON DELETE CASCADE"
+ "FOREIGN KEY("+Item_id+ ") REFERENCES "+ contentTable+ "("+contentID+"));");

You would need an ALTER TABLE DROP CONSTRAINT command but SQLite doesn't support this, see How do I DROP a constraint from a sqlite (3.6.21) table? for a workaround.

This is an old question, but it's best to provide an updated answer.
Since API 16 (Aka Android 4.1), it's possible to turn on the FK constraints using SQLiteDatabase#setForeignKeyConstraintsEnabled(boolean enabled).
As per the docs:
Sets whether foreign key constraints are enabled for the database.
By default, foreign key constraints are not enforced by the database.
This method allows an application to enable foreign key constraints.
It must be called each time the database is opened to ensure that
foreign key constraints are enabled for the session.
To make this work, inside your custom SQLiteOpenHelper use the following code:
#Override
public void onConfigure(SQLiteDatabase db) {
// Enable FK constraints.
db.setForeignKeyConstraintsEnabled(true);
super.onConfigure(db);
}

Related

Error while inserting data into Database using content values

I am trying to insert data in database but it is giving me following error.
table places has no column named PLACE_NAME (code 1): , while compiling: INSERT INTO places(PLACE_NAME,IS_SELECTED,placeID,LONGITUDE,LATITUDE) VALUES (?,?,?,?,?)
here is how I am creating my Database Table
// Create a table to hold the places data
final String SQL_CREATE_PLACES_TABLE = "CREATE TABLE IF NOT EXISTS " + PlaceContract.PlaceEntry.TABLE_NAME + " (" +
PlaceContract.PlaceEntry._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," + PlaceContract.PlaceEntry.COLUMN_PLACE_NAME + " VARCHAR, " +
PlaceContract.PlaceEntry.COLUMN_PLACE_LATITUDE + " VARCHAR, " + PlaceContract.PlaceEntry.COLUMN_PLACE_LONGITUDE + " VARCHAR, "+
PlaceContract.PlaceEntry.COLUMN_PLACE_IS_SELECTED + " VARCHAR, " +
PlaceContract.PlaceEntry.COLUMN_PLACE_ID + " TEXT NOT NULL, " +
"UNIQUE (" + PlaceContract.PlaceEntry.COLUMN_PLACE_ID + ") ON CONFLICT REPLACE" +
"); ";
please help me what I am doing wrong ....
The most common causes of column not found are typing errors and a misconception in regards to the onCreate method.
The former is unlikely if you are consistently using a single source for the column name e.g. if you use PlaceContract.PlaceEntry.COLUMN_PLACE_NAME to refer to the place_name column.
With the latter, the onCreate method only runs automatically when the database is created, any changes made to the schema, such as adding columns, will not be applied. Thus if you changed the CREATE SQL string to add the PLACE_NAME column that column will not be added.
When developing an App and when the data can be lost then then there are three quick ways to rectify the situation.
Delete the App's data and rerun (the database will be deleted (unless the database is stored outside of the App (not recommended and not the typical scenario))).
Uninstall the App and rerun (also delete's the App's data).
IF the onUpgrade will drop the said table or tables and then recreate the tables (generally by calling the onCreate method) then the database version can be increased (this is the 4th parameter of the super call when constructing the Database Helper class (i.e. the class that extends SQLiteOpenHelper)).
If the data in the database cannot be lost, then the alternative is to use the ALTER to add the column or to create another table, copy the data from the original table and then drop the original table and use ALTER to rename the new table to be the original table.

Create a UNIQUE constraint on two columns(Only if both exist in the database). If one of the columns is different, I don't want to constrain it

In the snippet below I have two columns with UNIQUE (MEMBER_NAME & KEY_CALORIES). I only want it to be UNIQUE if both column are the same. I am trying to get UNIQUE (MEMBER_NAME, KEY_CALORIES), or something on those lines.
Example of what I am trying to accomplish:
Perhaps the user enters a MEMBER_NAME(but that name is already in the databsae) but KEY_CALORIES is different I want to be able to add that item to the SQLite database. If the user enters an already existing MEMBER_NAME and KEY_CALORIES (only when they are both the same) I want it to be UNIQUE. If there is trouble understanding what I am trying to accomplish, I will update my question.
// TABLE CREATION STATEMENT
private static final String CREATE_TABLE = "create table " + TABLE_MEMBER
+ "(" + MEMBER_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ MEMBER_NAME + " TEXT NOT NULL UNIQUE," + KEY_CALORIES
+ " INT NOT NULL UNIQUE);";
Using UNIQUE(MEMBER_NAME) constraint means that you can only insert a MEMBER_NAME once. What you want is a UNIQUE constraint on MEMBER_KEY and KEY_CALORIES.
You can use UNIQUE(MEMBER_KEY,KEY_CALORIES) as the constraint, which means that their combined values should be unique. Duplicates are allowed on both columns, as long as this combination is unique.
Possible duplicate / reference answer :
Sqlite table constraint - unique on multiple columns

foreign key constraint ON DELETE CASCADE not working in sqlite database on android

I have "days" table created as follows
"create table days(" +
"day_id integer primary key autoincrement, " +
"conference_id integer , " +
"day_date text, " +
"day_start_time text, " +
"day_end_time text, " +
"day_summary text, " +
"day_description text)";
and i have tracks table created as follows
CREATE_TABLE_TRACK = "create table track(" +
"track_id integer primary key autoincrement," +
"day_id integer,"+
"track_name text," +
"track_description text," +
" FOREIGN KEY(day_id) REFERENCES days(day_id) ON DELETE CASCADE )";
as shown above i have foreign key day_id referencing to the day_id of table days...
So what i want is if i delete the day then corresponding track should also be deleted... But it does't happen in my case..
I have sqlite with version 3.5.9
And also i have added 1 line in my helper class as
> db.execSQL("PRAGMA foreign_keys=ON;");
but is still won't work.. please help me out..
Cascading delete isn't supported until Sqlite version 3.6.19, which is first included on Android 2.2.
Fortunately there is an alternative.
You can execute another query like this below your create table query:
db.execSQL("CREATE TRIGGER delete_days_with track BEFORE DELETE ON track "
+ "FOR EACH ROW BEGIN"
+ " DELETE FROM days WHERE track.day_id = days.day_id "
+ "END;");
Note that delete_days_with_track is just a name descriptive of what the trigger does, and this is just the pattern I use; I believe you could name it anything you wish.
According to the SQLite Documentation support for Foreign Keys was not added until 3.6.19.
Using 3.5.9 you'll have to do your cascade deletions in some other manner.

How to do SQL Insert or Replace like operation without changing primary key?

I'm trying to insert a record into a SQLite database table. The table has a Unique constraint on a column "URL" and a primary key auto increment integer "_id".
I'm using insert or replace as my conflict resolution, since I need the new data to be persisted. However, this method is incrementing the primary key and messing up some foreign keys in other tables.
What's the best way to overwrite the record without updating the _id?
The simple answer is to stop using Replace syntax. This causes the old record to be deleted then a new one added ... which would increment your index.
Utilize the UPDATE syntax to handle conflicts instead
EDIT:
If you are really partial to the Replace syntax then it will come at a cost. You will need to write additional code that updates all prev occurrences of the old index to the new one. Not overly hard but this will correct the issue of synchronizing indexes
Documentation [Listed under REPLACE section little ways down the page]: http://www.sqlite.org/lang_conflict.html
this is my code of SQLite
"CREATE TABLE IF NOT EXISTS posts (" +
"_id integer NOT NULL," +
"id_language integer NOT NULL" +
");" +
"CREATE UNIQUE INDEX posts_idx ON posts(_id, id_language);";
"INSERT OR REPLACE INTO " + DB_TABLE + " (" + formulateColumns() + ") " +
"VALUES (" + formulateValues(v) + ");");

Android SQLite - How To Update The Record ID Number After Deleting Records

I can look up records by values and/or ID
I can add records
I can delete All records
I can delete a specific record (by either value or ID)
But, the record ID only increments - it never adjusts to reflect the number of remaining records after deleting a record.
I haven't found anything on this subject (not even in the Doc's)
What/How do I do this?
Thanks
The declaration for this part of the db follows...
String sql =
"create table "
+ TABLE
+ "( " + BaseColumns._ID
+ " integer primary key autoincrement, "
+ THE_NUMBER + " integer, "
+ FAV_NAME + " text not null);";
Rather than deleting this post, I'll post the ref to the answer (it's at SQL's site).
link text

Categories

Resources