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 the documentation.
In SQLite 4.x, FK constraints will be enabled by default.
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 the documentation.
In SQLite 4.x, FK constraints will be enabled by default.
Foreign key constraint does not apply
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.
Enabling Foreign key constraints in SQLite
Finally figured this out from this post. The PRAGMA foreign_key setting does not persist but you can set it every time the connection is made in the ConnectionString. This allows you to use Visual Studio's table adapters.
- Make sure you have the latest version (1.0.73.0) of system.data.sqlite installed (1.0.66.0 will not work).
- Change your ConnectionString to
data source=C:\Dbs\myDb.db;foreign keys=true;
(replace C:\Dbs\myDb.db with your sqlite database).
SQLite Foreign keys not working correctly
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.
Foreign Key constraint is not working properly on SQLite
The problem is this:
ON DELETE SET DEFAULT
with the definition of the foreign keys in games
, because the default value for all of them is defined to be 0
which (I suspect) does not correspond to a valid id of the corresponding referenced tables.
What you can do is define the foreign keys as nullable and with ON DELETE SET NULL
like this:
CREATE TABLE IF NOT EXISTS games (
g_id INTEGER NOT NULL,
g_name TEXT NOT NULL,
g_genre INTEGER, -- nullable
g_pub INTEGER, -- nullable
year_released INTEGER NOT NULL,
original_platform INTEGER, -- nullable
PRIMARY KEY(g_id),
FOREIGN KEY(g_genre) REFERENCES game_genre(genre_id) ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY(g_pub) REFERENCES game_publisher(gp_id) ON DELETE SET NULL ON UPDATE CASCADE,
FOREIGN KEY(original_platform) REFERENCES platform(platform_id) ON DELETE SET NULL ON UPDATE CASCADE
)
Now when you delete a row from a parent table, the child key value will be set to NULL
, which is allowed.
Finally, for the question:
Do I have to turn ON the foreign key constraint every time I make a
connection to the database?
the answer is yes, if you are going to use operations involving the integerity of the foreign keys, like the insertion of a new row or update a row in the child table games
or the modification of rows (deletions or updates) of the parent tables.
Non-existent foreign key doesn't cause error in SQLite
From the relevant documentation:
In order to use foreign key constraints in SQLite, the library must be compiled with neither
SQLITE_OMIT_FOREIGN_KEY
orSQLITE_OMIT_TRIGGER
defined. IfSQLITE_OMIT_TRIGGER
is defined butSQLITE_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 usingPRAGMA 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
How do you enforce foreign key constraints in SQLite through Java?
When you look at the SQLite Foreign Key Support page I would interpret that
- SQLlite has to be compiled with foreign key support
- You still have to turn it on for each connection with PRAGMA
- You have to define the foreign key as constraint when you create the table
Ad 1) Quoted from here:
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).
What is your result for PRAGMA foreign_keys;
?
Update: from your comment I see you are using 3.6.14.2, this means your version is not supporting foreign key constraints! So you have to update SQLite, if this is possible!
Ad 2) Your first code snippet executes the PRAGMA as statement, I don't think this will work. The third snipped didn't work based on your comment: the SQLite driver interprets the whole string as the location of the database, instead of taking the "foreign keys=true" part as connection settings". So only the second snippet will work.
Ad 3) Did you create the table with foreign key support? Quoted from here:
CREATE TABLE artist(
artistid INTEGER PRIMARY KEY,
artistname TEXT
);
CREATE TABLE track(
trackid INTEGER,
trackname TEXT,
trackartist INTEGER,
FOREIGN KEY(trackartist) REFERENCES artist(artistid)
);
SQLite: Why is foreign key constraint not working here?
You need to first enable foreign key enforcement:
PRAGMA foreign_keys=on;
Related Topics
Common Table Expression, Why Semicolon
How to Avoid Multiple Function Evals With the (Func()).* Syntax in a Query
When or Why Would You Use a Right Outer Join Instead of Left
SQL String Comparison, Greater Than and Less Than Operators
Can a Check Constraint Relate to Another Table
How to Convert an Integer (Time) to Hh:Mm:Ss::00 in SQL Server 2008
How to Include a PHP Variable Inside a MySQL Statement
Run All SQL Files in a Directory
SQL - Many-To-Many Table Primary Key
Left Outer Join Using + Sign in Oracle 11G
Database-Independent SQL String Concatenation in Rails
How to Determine the Last Day of the Previous Month Using Postgresql
Fastest Way to Update 120 Million Records
Create a Pivot Table With Postgresql
Why Rlwrap Echos "Redundantly" What I Type from the Keyboard