如何将外键添加到现有的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进行任意更改的步骤如下:
- 如果启用了外键约束,则使用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重build与表X相关联的索引和触发器。也许使用上面步骤3中保存的触发器和索引的旧格式作为指导,根据需要进行更改。
- 如果任何视图以受模式更改影响的方式引用表X,则使用DROP VIEW删除这些视图,并重新创build这些视图,以便使用CREATE VIEW来适应模式更改所需的任何更改。
- 如果最初启用了外键约束,则运行PRAGMA foreign_key_check以validation模式更改没有破坏任何外键约束。
- 提交事务在第2步中开始。
- 如果外键约束最初启用,现在重新启用它们。
上述过程是完全一般的,即使模式更改导致存储在表中的信息发生更改,也是可行的。 因此,上面的完整过程适用于删除列,更改列的顺序,添加或删除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