I'm using SQLite with C# and have some tables with foreign keys defined.
Now, I know that by default foreign key constraints are not enforced in SQLite, but I'd like to turn them ON.
Is it possible to do this through code? I have looked up a related question, but I'm not sure how to do it through C# code. I'm using the latest plug-in of SQLite available for Visual Studio 2008 for designing my tables.
conn.Open();
SQLiteCommand cmd = new SQLiteCommand("PRAGMA foreign_keys = ON", conn);
cmd.ExecuteNonQuery();
conn.Close();
I need this change to persist when this connection is reopened. Is it possible?
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).
Turn on the pragma:
PRAGMA foreign_keys = ON;
You can execute this just like any other SQL statement.
I too struggled with this issue. I decided to investigate the full connection string generated in SQLDriverConnect() when connecting to the database. This is what it returned:
'Driver={SQLite3 ODBC Driver};Database=C:\Users\Staples\Documents\SQLLiteTest.s3db;StepAPI=;SyncPragma=;NoTXN=;Timeout=;ShortNames=;LongNames=;NoCreat=;NoWCHAR=;FKSupport=;JournalMode=;OEMCP=;LoadExt=;BigInt=;PWD='
As you can see there is a FKSupport property.
After adding FKSupport=True; to my connection string it returned this:
'Driver={SQLite3 ODBCDriver};Database=C:\Users\Staples\Documents\SQLLiteTest.s3db;StepAPI=;SyncPragma=;NoTXN=;Timeout=;ShortNames=;LongNames=;NoCreat=;NoWCHAR=;FKSupport=True;JournalMode=;OEMCP=;LoadExt=;BigInt=;PWD='
And voila! foreign key contraints are enforced.
Another solution is to do the "PRAGMA foreign_keys=ON" with every query.
SQLiteConnection connection = new SQLiteConnection("Data Source=" + dbSQLite + ";Read Only=False;");
connection.Open();
SQLiteCommand mycommand = new SQLiteCommand(connection);
mycommand.CommandText = "PRAGMA foreign_keys=ON";
mycommand.ExecuteNonQuery();
mycommand.CommandText = "DELETE FROM table WHERE ID=x";
mycommand.ExecuteReader();
connection.Close();
If you put it in a function to which you pass the CommandText you can reuse it.
These should provide the information you're looking for:
http://www.sqlite.org/faq.html#q22
http://www.sqlite.org/foreignkeys.html#fk_enable
In short, versions before 3.6.19 don't enforce foreign keys at all, but they can be simulated using triggers; starting with 3.6.19, foreign keys can be enforced, but this needs to be enabled per connection using the PRAGMA foreign_keys = ON statement, and sqlite must be compiled with trigger and foreign key support enabled (which I'd expect to be the case for any binary distribution).
Looks like you can just execute the SQL command PRAGMA foreign_keys = ON; on your DB connection just like you would a Select or an Update statement. Though you have to make sure your SQLite was compiled with foreign keys and such. See Here.
Add to your connection string: ";EnforceFKConstraints=Yes|True|1;"
In C++ store app the following code helped me to enable PRAGMA foreign_keys
sqlite3_stmt* stmt;
sqlite3_prepare(db, "PRAGMA foreign_keys = ON;", -1, &stmt, 0);
sqlite3_step(stmt);
I called this after creating db using the call of
int rc = sqlite3_open16(path->Data(), &db);
来源:https://stackoverflow.com/questions/4254371/enabling-foreign-key-constraints-in-sqlite