如何将外键添加到现有的sqlite(3.6.21)表?

我有下面的表格:

CREATE TABLE child( id INTEGER PRIMARY KEY, parent_id INTEGER, description TEXT); 

如何在parent_id上添加外键约束? 假设外键已启用。

大多数例子假设你正在创build表 – 我想将约束添加到现有的。

你不能。

尽pipe向表中添加外键的SQL-92语法如下所示:

 ALTER TABLE child ADD CONSTRAINT fk_child_parent FOREIGN KEY (parent_id) REFERENCES parent(id); 

SQLite不支持 ALTER TABLE命令的ADD CONSTRAINT变体( sqlite.org:SQLite没有实现的SQLfunction )。

因此,在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约束创build新表,然后将数据从临时表中复制回来。 ( sqlite.org – 常见问题解答:Q11 )

如果您更改表并添加使用约束的列,则可以添加约束。

首先,创build没有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的模式devise进行任意更改的步骤如下:

  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 TABLE X.
  7. 使用以下命令将new_X的名称更改为X:ALTER TABLE new_X RENAME TO X.
  8. 使用CREATE INDEX和CREATE TRIGGER重build与表X相关联的索引和触发器。也许使用上面步骤3中保存的触发器和索引的旧格式作为指导,根据需要进行更改。
  9. 如果任何视图以受模式更改影响的方式引用表X,则使用DROP VIEW删除这些视图,并重新创build这些视图,以便使用CREATE VIEW来适应模式更改所需的任何更改。
  10. 如果最初启用了外键约束,则运行PRAGMA foreign_key_check以validation模式更改没有破坏任何外键约束。
  11. 提交事务在第2步中开始。
  12. 如果外键约束最初启用,现在重新启用它们。

上述过程是完全一般的,即使模式更改导致存储在表中的信息发生更改,也是可行的。 因此,上面的完整过程适用于删除列,更改列的顺序,添加或删除UNIQUE约束或PRIMARY KEY,添加CHECK或FOREIGN KEY或NOT NULL约束或更改列的数据types。

如果您使用Firefox附加的sqlitepipe理器,您可以执行以下操作:

而不是再次删除和创build表,可以像这样修改它。

在“列”文本框中,右键单击列出的最后一列名称以调出上下文菜单,然后select“编辑列”。 请注意,如果TABLE定义中的最后一列是PRIMARY KEY,则需要首先添加一个新列,然后编辑新列的列types以添加​​FOREIGN KEY定义。 在列types框中,附加一个逗号和

 FOREIGN KEY (parent_id) REFERENCES parent(id) 

数据types后定义。 单击“更改”button,然后单击“危险操作”对话框中的“是”button。

参考: Sqlitepipe理器

您可以!

尝试下面的命令,你不需要临时表。 它在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