Включение ограничений внешнего ключа в SQLite
Я использую SQLite с С# и имею несколько таблиц с заданными внешними ключами.
Теперь я знаю, что по умолчанию ограничения внешнего ключа не применяются в SQLite, но я бы хотел включить их.
Можно ли это сделать с помощью кода? Я просмотрел связанный question, но я не уверен, как это сделать с помощью кода на С#. Я использую последний подключаемый модуль SQLite, доступный для Visual Studio 2008 для проектирования моих таблиц.
conn.Open();
SQLiteCommand cmd = new SQLiteCommand("PRAGMA foreign_keys = ON", conn);
cmd.ExecuteNonQuery();
conn.Close();
Мне нужно, чтобы это изменение сохранялось при повторном открытии этого соединения. Возможно ли это?
Ответы
Ответ 1
Наконец понял это из этого сообщения. Параметр PRAGMA foreign_key не сохраняется, но вы можете устанавливать его каждый раз, когда соединение выполняется в ConnectionString. Это позволяет использовать адаптеры таблицы Visual Studio.
- Убедитесь, что установлена последняя версия (1.0.73.0) для system.data.sqlite(1.0.66.0 не будет работать).
- Измените ConnectionString на
data source=C:\Dbs\myDb.db;foreign keys=true;
(замените C:\Dbs\myDb.db на базу данных sqlite).
Ответ 2
Включите прагму:
PRAGMA foreign_keys = ON;
Вы можете выполнить это так же, как и любой другой оператор SQL.
Ответ 3
Я тоже боролся с этой проблемой. Я решил исследовать полную строку соединения, сгенерированную в SQLDriverConnect()
при подключении к базе данных. Это то, что он вернул:
'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='
Как вы видите, есть свойство FKSupport
.
После добавления FKSupport=True;
в мою строку подключения он вернул это:
'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='
И вуаля! нарушены внешние ограничения.
Ответ 4
Они должны предоставить информацию, которую вы ищете:
http://www.sqlite.org/faq.html#q22
http://www.sqlite.org/foreignkeys.html#fk_enable
Короче говоря, версии до 3.6.19 вообще не применяют внешние ключи, но их можно моделировать с помощью триггеров; начиная с 3.6.19, внешние ключи могут быть принудительно введены, но это необходимо включить для каждого соединения с помощью оператора PRAGMA foreign_keys = ON
, и sqlite должен быть скомпилирован с включенной поддержкой триггера и внешнего ключа (что я ожидал бы в случае любое двоичное распределение).
Ответ 5
Другим решением является выполнение "PRAGMA foreign_keys = ON" с каждым запросом.
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();
Если вы поместите его в функцию, которой вы передаете CommandText, вы можете ее повторно использовать.
Ответ 6
Похоже, вы можете просто выполнить команду SQL PRAGMA foreign_keys = ON;
в вашем соединении с БД так же, как вы бы сделали запрос Select или Update. Хотя вы должны убедиться, что ваш SQLite был скомпилирован с помощью внешних ключей и т.д. См. здесь.
Ответ 7
Добавьте в строку подключения: ";EnforceFKConstraints=Yes|True|1;"
Ответ 8
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);