SQLite Foreign keys not working correctly [duplicate] - sqlite

This question already has answers here:
Does SQLite3 not support foreign key constraints?
(5 answers)
Closed 11 months ago.
The following is a query for creating a table:
CREATE TABLE "FacilityRating"(
"FacilityRatingId" INTEGER PRIMARY KEY NOT NULL,
"Stars" VARCHAR,
"Facility_FacilityId" INTEGER,
"User_UserId" INTEGER,
FOREIGN KEY (Facility_FacilityId)
REFERENCES Facility(FacilityId)
ON DELETE CASCADE
ON UPDATE CASCADE,
FOREIGN KEY (User_UserId)
REFERENCES User(UserId)
ON DELETE CASCADE
ON UPDATE CASCADE
)
However, when I insert a new row in Facility_FacilityId and User_UserId with some random numbers, SQLite does not give error but adds it anyway.
Here is a snapshot:
Any hint what is going on here? I am using SQLite Manager, an Add-on for Mozilla Firefox

The documentation says:
Foreign key constraints must be enabled by the application at runtime, using the PRAGMA foreign_keys command. For example:
sqlite> PRAGMA foreign_keys = ON;
Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database connection.

#Override
public void onConfigure(SQLiteDatabase db) {
super.onConfigure(db);
db.setForeignKeyConstraintsEnabled(true);
}

Related

Foreign key constraint does not apply

I have defined a foreign key. To check it, i insert wrong values to the table that has the foreign key. No error were printed and the values were added succefully. I do not know if i am running some old version of sqlite3 or something like that, i am completely new to this area.
create table ref(value1 int ,value2,primary key(value1));
create table for(value1 int,value3 int,primary key(value3),foreign key(value1)references ref(value1));
insert into for values (1,1);
This was added succefully.
Foreign key constraints are disabled by default as it is explained here: SQLite Foreign Key Support.
To enable them execute first:
PRAGMA foreign_keys = ON;
See the demo.

Non-existent foreign key doesn't cause error in SQLite

The following code should IMO produce an error because the user_id=1 doesn't exist. Why does it work?
CREATE TABLE users (
user_id int PRIMARY KEY,
email text UNIQUE
);
CREATE TABLE claimed (
account_id int PRIMARY KEY,
user_id int,
domain text,
FOREIGN KEY (user_id) REFERENCES users (user_id)
);
INSERT INTO claimed
(user_id, domain)
VALUES (1, "abcd");
From the relevant documentation:
In order to use foreign key constraints in SQLite, the library must be compiled with neither SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined. If SQLITE_OMIT_TRIGGER is defined but SQLITE_OMIT_FOREIGN_KEY is not, then SQLite behaves as it did prior to version 3.6.19 (2009-10-14) - foreign key definitions are parsed and may be queried using PRAGMA foreign_key_list, but foreign key constraints are not enforced.
and:
Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database connection.
and:
Assuming the library is compiled with foreign key constraints enabled, it must still be enabled by the application at runtime, using the PRAGMA foreign_keys command. For example:
sqlite> PRAGMA foreign_keys = ON;
Apparently you should use PRAGMA foreign_keys = ON at the top of your connection, and potentially rebuild with the appropriate options (though if you installed from package then I would personally assume that this has been done).
Source: Google sqlite foreign key, first result

The child's keys don't get deleted when I delete the parent key

I made a database via SQLite which looks like the following:
and I created a table called as books like this:
CREATE TABLE books (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "title-book" TEXT, witer TEXT, comment TEXT, "intro-img" TEXT, "avalable-count" integer, "total-count" integer, "publisher-id" INTEGER REFERENCES publisher (id) ON DELETE CASCADE ON UPDATE CASCADE, "category-id" INTEGER REFERENCES categories (id) ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY ("publisher-id") REFERENCES publisher (id) ON DELETE CASCADE ON UPDATE CASCADE);
When I delete a category that is a parent key for books category-id then I see books table having the child key rows that include that category didn't remove and they exist as they were like in the following pictures:
SQLite 3.6.19 and older doesn't support Foreign Keys.
If you have a newer version you can check the support using:
PRAGMA foreign_keys
If it returns "no data" it means there is no support installed (because it was compiled with SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined), while returning 0 means "supported but disabled" (default) and 1 means "supported and enabled".
You can enable at runtime using
PRAGMA foreign_keys = ON;
Be aware this must be enabled for every database connection:
Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database connection.
Also consider:
It is not possible to enable or disable foreign key constraints in the middle of a multi-statement transaction (when SQLite is not in autocommit mode). Attempting to do so does not return an error; it simply has no effect.
REFERENCE: https://sqlite.org/foreignkeys.html

SQLite won't throw error when inserting non-existing foreign key value [duplicate]

This question already has answers here:
Does SQLite3 not support foreign key constraints?
(5 answers)
Closed 6 years ago.
I have a litte problem with my SQLite database, especially with the following tables:
CREATE TABLE foo (
key INTEGER PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE bar (
_id INTEGER PRIMARY KEY,
key INTEGER NOT NULL,
what TEXT NOT NULL,
else TEXT,
FOREIGN KEY (key) REFERENCES foo (key) DEFERRABLE INITIALLY DEFERRED
);
If I understand the SQLite documentation the right way, attempting to insert a row into bar that does not correspond to any row in the foo table should fail and thow an error or something.
Unfortunately the following command works, even if no key 42 existis in foo:
INSERT INTO bar (key, what, else) VALUES (42, "something", "else");
This will create a row in bar with the given values (key = 42), while there exists no row in foo with the key 42.
Is it me or what is wrong here?
As posted by #kijin on Does SQLite3 not support foreign key constraints?
In SQLite 3.x, you have to make the following query every time you connect to an SQLite database:
PRAGMA foreign_keys = ON;
Otherwise SQLite will ignore all foreign key constraints.
Why every time? Backwards compatibility with SQLite 2.x, according to the documentation.
In SQLite 4.x, FK constraints will be enabled by default.

SQLite many-to-many relationship?

I'm trying to set up a SQLite3 database with foos and bars and a many-to-many relation between them. This is what I've got so far:
CREATE TABLE foo(
id INTEGER PRIMARY KEY NOT NULL,
foo_col INTEGER NOT NULL
);
CREATE TABLE bar(
id INTEGER PRIMARY KEY NOT NULL,
bar_col TEXT NOT NULL
);
CREATE TABLE foobar(
foo_id INTEGER,
bar_id INTEGER,
FOREIGN KEY(foo_id) REFERENCES foo(id) ON DELETE CASCADE,
FOREIGN KEY(bar_id) REFERENCES bar(id) ON DELETE CASCADE
);
CREATE INDEX fooindex ON foobar(foo_id);
CREATE INDEX tagindex ON foobar(tag_id);
...but it doesn't seem to be working. I can delete a row from foo and it doesn't affect foobar. What am I doing wrong?
Taken from this site, http://www.sqlite.org/foreignkeys.html.
Assuming the library is compiled with foreign key constraints enabled, it must still be enabled by the application at runtime, using the PRAGMA foreign_keys command. For example:
sqlite> PRAGMA foreign_keys = ON;
Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database connection separately. (Note, however, that future releases of SQLite might change so that foreign key constraints enabled by default. Careful developers will not make any assumptions about whether or not foreign keys are enabled by default but will instead enable or disable them as necessary.) The application can can also use a PRAGMA foreign_keys statement to determine if foreign keys are currently enabled. The following command-line session demonstrates this:
sqlite> PRAGMA foreign_keys;
0
sqlite> PRAGMA foreign_keys = ON;
sqlite> PRAGMA foreign_keys;
1
sqlite> PRAGMA foreign_keys = OFF;
sqlite> PRAGMA foreign_keys;
0
Tip: If the command "PRAGMA foreign_keys" returns no data instead of a single row containing "0" or "1", then the version of SQLite you are using does not support foreign keys (either because it is older than 3.6.19 or because it was compiled with SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined).
It is not possible to enable or disable foreign key constraints in the middle of a multi-statement transaction (when SQLite is not in autocommit mode). Attempting to do so does not return an error; it simply has no effect.

Resources