我有下表:
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:SQLite未实现的SQL功能).
因此,在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的模式设计进行任意更改的步骤如下:
如果启用了外键约束,请使用PRAGMA foreign_keys = OFF禁用它们.
开始交易.
记住与表X关联的所有索引和触发器的格式.下面的步骤8中将需要此信息.一种方法是运行如下查询:SELECT类型,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约束,或更改列的数据类型等.