У меня есть следующая таблица:
CREATE TABLE child(
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT);
Как добавить ограничение внешнего ключа на parent_id? Предположим, что включены внешние ключи.
В большинстве примеров предполагается, что вы создаете таблицу - я бы хотел добавить ограничение к существующему.
Вы не можете.
Хотя синтаксис SQL-92 для добавления внешнего ключа в вашу таблицу будет выглядеть следующим образом:
ALTER TABLE child ADD CONSTRAINT fk_child_parent
FOREIGN KEY (parent_id)
REFERENCES parent(id);
SQLite не поддерживает вариант ADD CONSTRAINT
команды ALTER TABLE
(sqlite.org: функции SQL, которые SQLite Не выполняется).
Следовательно, единственный способ добавить внешний ключ в sqlite 3.6.1 - во время CREATE TABLE
следующим образом:
CREATE TABLE child (
id INTEGER PRIMARY KEY,
parent_id INTEGER,
description TEXT,
FOREIGN KEY (parent_id) REFERENCES parent(id)
);
К сожалению, вам придется сохранить существующие данные во временной таблице, отбросить старую таблицу, создать новую таблицу с ограничением FK, а затем скопировать данные обратно из временной таблицы. (sqlite.org - FAQ: Q11)
RENAME TO
является одним из немногих вариантов ALTER TABLE
который в настоящее время поддерживается в sqlite 3.
Вы можете добавить ограничение, если вы измените таблицу и добавьте столбец, который использует ограничение.
Сначала создайте таблицу без parent_id:
CREATE TABLE child(
id INTEGER PRIMARY KEY,
description TEXT);
Затем измените таблицу:
ALTER TABLE child ADD COLUMN parent_id INTEGER REFERENCES parent(id);
Пожалуйста, проверьте https://www.sqlite.org/lang_altertable.html#otheralter
Единственными командами изменения схемы, напрямую поддерживаемыми SQLite, являются команды "переименовать таблицу" и "добавить столбец", показанные выше. Однако, приложения могут вносить другие произвольные изменения в формат таблицы используя простую последовательность операций. Шаги по созданию произвольных изменения в схеме схемы некоторой таблицы X выглядят следующим образом:
- Если ограничения внешнего ключа включены, отключите их с помощью PRAGMA foreign_keys = OFF.
- Запустите транзакцию.
- Помните формат всех индексов и триггеров, связанных с таблицу X. Эта информация потребуется на шаге 8 ниже. Один из способов сделайте это, чтобы выполнить запрос следующим образом: SELECT type, sql FROM sqlite_master WHERE tbl_name = 'X'.
- Используйте CREATE TABLE для создания новой таблицы "new_X", которая находится в желаемый пересмотренный формат таблицы X. Убедитесь, что имя "new_X" не сталкивается с каким-либо существующим именем таблицы, конечно.
- Перенос содержимого из X в new_X с помощью оператора типа INSERT INTO new_X SELECT... FROM X.
- Отбросьте старую таблицу X: DROP TABLE X.
- Измените имя new_X на X, используя: ALTER TABLE new_X RENAME TO X.
- Используйте CREATE INDEX и CREATE TRIGGER для восстановления индексов и триггеры, связанные с таблицей X. Возможно, используйте старый формат триггеры и индексы, сохраненные с шага 3 выше, в качестве руководства, изменения в зависимости от изменений.
- Если какие-либо представления относятся к таблице X способом, на который влияет измените схему, затем отбросьте эти представления с помощью DROP VIEW и заново создайте их с любыми изменениями, необходимыми для размещения схемы с помощью CREATE VIEW.
- Если ограничения внешнего ключа были первоначально включены, запустите PRAGMA foreign_key_check, чтобы проверить, не изменилось ли изменение схемы любые ограничения внешнего ключа.
- Завершить транзакцию, начатую на шаге 2.
- Если ограничения внешних ключей были первоначально включены, повторно их использовать Теперь.
Процедура выше полностью общая и будет работать, даже если изменение схемы приводит к изменению информации, хранящейся в таблице. Так полная процедура выше подходит для удаления столбца, изменение порядка столбцов, добавление или удаление ограничения UNIQUE или PRIMARY KEY, добавив ограничения CHECK или FOREIGN KEY или NOT NULL, или, например, изменение типа данных для столбца.
Если вы используете дополнительный SQL-менеджер Firefox, вы можете сделать следующее:
Вместо того, чтобы отбрасывать и создавать таблицу снова, можно просто изменить ее следующим образом.
В текстовом поле "Столбцы" щелкните правой кнопкой мыши по последнему имени столбца, чтобы отобразить контекстное меню и выберите "Редактировать столбцы". Обратите внимание, что если последний столбец в определении TABLE является PRIMARY KEY, тогда необходимо будет сначала добавить новый столбец, а затем изменить тип столбца нового столбца, чтобы добавить определение FOREIGN KEY. В поле "Тип столбца" добавьте запятую и
FOREIGN KEY (parent_id) REFERENCES parent(id)
после типа данных. Нажмите кнопку "Изменить", а затем нажмите кнопку "Да" в диалоговом окне "Опасная операция".
Ссылка: Sqlite Manager
ВЫ МОЖЕТЕ!
Попробуйте выполнить следующую команду, и вам не нужна временная таблица. Это работает для меня в Android Studio.
db.execSQL("alter table child add column newCol integer REFERENCES parent(parentId)");
Сначала добавьте столбец в дочернюю таблицу Cid
как int
, затем alter table
с помощью кода ниже. Таким образом вы можете добавить внешний ключ Cid
в качестве основного ключа родительской таблицы и использовать его в качестве внешнего ключа в дочерней таблице... надеюсь, что это поможет вам, поскольку это полезно для меня:
ALTER TABLE [child]
ADD CONSTRAINT [CId]
FOREIGN KEY ([CId])
REFERENCES [Parent]([CId])
ON DELETE CASCADE ON UPDATE NO ACTION;
GO