Intereting Posts
Как создать таблицу фактов истории? Каков наилучший способ выбрать несколько строк по ID в sql? Postgres GROUP BY на внутреннем поле jsonb Использование fn_Split в SQL-запросе Как преобразовать текстовое поле в таблицу Access в текстовую заметку с использованием VBA Запрос LINQ для форума Объемная вставка SQL Server – «Ошибка преобразования данных массовой загрузки» IN vs OR Oracle, что быстрее? SQL – нужен запрос, чтобы получить самое последнее сообщение в каждом потоке, в котором пользователь является частью SQL, ODG Postgres, что они и зачем они полезны? Как проверить, хорошо ли INSERT хранится функция? Создайте строку с разделителями из запроса в DB2 SQL: установить существующий столбец как первичный ключ в MySQL Поставщик OLE DB «Microsoft.ACE.OLEDB.12.0» для связанного сервера «(null)» Ошибка Postgres: более чем одна строка, возвращаемая подзапросом, используемым как выражение

Как добавить внешний ключ в существующую таблицу sqlite (3.6.21)?

У меня есть следующая таблица:

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 )

Вы можете добавить ограничение, если вы измените таблицу и добавьте столбец, который использует ограничение.

Во-первых, создайте таблицу без 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 заключаются в следующем:

  1. Если ограничения внешнего ключа включены, отключите их с помощью PRAGMA foreign_keys = OFF.
  2. Запустите транзакцию.
  3. Помните формат всех индексов и триггеров, связанных с таблицей X. Эта информация понадобится на шаге 8 ниже. Один из способов сделать это – запустить такой запрос, как: SELECT type, sql FROM sqlite_master WHERE tbl_name = 'X'.
  4. Используйте CREATE TABLE для создания новой таблицы «new_X», которая находится в желаемом пересмотренном формате таблицы X. Убедитесь, что имя «new_X» не сталкивается с каким-либо существующим именем таблицы, конечно.
  5. Перенесите содержимое из X в new_X с помощью инструкции, например: INSERT INTO new_X SELECT … FROM X.
  6. Отбросьте старую таблицу X: ТАБЛИЦА DROP X.
  7. Измените имя new_X на X, используя: ALTER TABLE new_X RENAME TO X.
  8. Используйте CREATE INDEX и CREATE TRIGGER для восстановления индексов и триггеров, связанных с таблицей X. Возможно, используйте старый формат триггеров и индексов, сохраненных с шага 3 выше, в качестве руководства, внося изменения, соответствующие изменениям.
  9. Если какие-либо представления относятся к таблице X таким образом, на которые влияет изменение схемы, то отбросьте эти представления с помощью DROP VIEW и заново создайте их с любыми изменениями, необходимыми для изменения схемы с помощью CREATE VIEW.
  10. Если ограничения внешнего ключа были первоначально включены, запустите PRAGMA foreign_key_check, чтобы убедиться, что изменение схемы не нарушило ограничений внешнего ключа.
  11. Завершите транзакцию, начатую на шаге 2.
  12. Если внешние ограничения ключей были первоначально включены, теперь их можно повторно использовать.

Вышеописанная процедура является полностью общей и будет работать, даже если изменение схемы приведет к изменению информации, хранящейся в таблице. Таким образом, полная процедура выше подходит для удаления столбца, изменения порядка столбцов, добавления или удаления ограничения 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)"); 

Да, вы можете, не добавляя новый столбец. Вы должны быть осторожны, чтобы делать это правильно, чтобы не повредить базу данных, поэтому вы должны полностью создать резервную копию своей базы данных, прежде чем пытаться это сделать:

 pragma writable_schema=1; // replace the entire table's SQL definition, where new_sql_definition contains the foreign key clause you want to add UPDATE SQLITE_MASTER SET SQL = new_sql_definition where name = 'child' and type = 'table'; // alternatively, you might find it easier to use replace, if you can match the exact end of the sql definition // for example, if the last column was my_last_column integer not null: UPDATE SQLITE_MASTER SET SQL = replace(sql, 'my_last_column integer not null', 'my_last_column integer not null, foreign key (col1, col2) references other_table(col1, col2)') where name = 'child' and type = 'table'; pragma writable_schema=0; 

В любом случае, вы, вероятно, захотите сначала увидеть, что такое определение SQL, прежде чем вносить какие-либо изменения:

 select sql from SQLITE_MASTER where name = 'child' and type = 'table'; 

Если вы используете подход replace (), вы можете обнаружить, что перед его выполнением сначала проверить свою команду replace (), выполнив:

 select update(sql, ...) from SQLITE_MASTER where name = 'child' and type = 'table'; 

Сначала добавьте столбец в дочернюю таблицу 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