首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将外键添加到现有的SQLite表中?

如何将外键添加到现有的SQLite表中?
EN

Stack Overflow用户
提问于 2009-12-11 07:22:51
回答 6查看 144.5K关注 0票数 159

我有下表:

代码语言:javascript
复制
CREATE TABLE child( 
  id INTEGER PRIMARY KEY, 
  parent_id INTEGER, 
  description TEXT);

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

大多数示例都假设您正在创建表-我想将约束添加到现有的表中。

EN

回答 6

Stack Overflow用户

发布于 2014-05-10 05:12:20

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

首先,创建不带parent_id的表:

代码语言:javascript
复制
CREATE TABLE child( 
  id INTEGER PRIMARY KEY,  
  description TEXT);

然后,alter table:

代码语言:javascript
复制
ALTER TABLE child ADD COLUMN parent_id INTEGER REFERENCES parent(id);
票数 68
EN

Stack Overflow用户

发布于 2017-12-29 11:07:06

是的,您可以,而无需添加新列。为了避免损坏数据库,您必须小心正确地执行此操作,因此在尝试此操作之前,您应该完全备份数据库。

对于您的特定示例:

代码语言:javascript
复制
CREATE TABLE child(
  id INTEGER PRIMARY KEY,
  parent_id INTEGER,
  description TEXT
);

--- create the table we want to reference
create table parent(id integer not null primary key);

--- now we add the foreign key
pragma writable_schema=1;
update SQLITE_MASTER set sql = replace(sql, 'description TEXT)',
    'description TEXT, foreign key (parent_id) references parent(id))'
) where name = 'child' and type = 'table';

--- test the foreign key
pragma foreign_keys=on;
insert into parent values(1);
insert into child values(1, 1, 'hi'); --- works
insert into child values(2, 2, 'bye'); --- fails, foreign key violation

或者更一般地说:

代码语言:javascript
复制
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定义:

代码语言:javascript
复制
select sql from SQLITE_MASTER where name = 'child' and type = 'table';

如果您使用replace()方法,您可能会发现,在执行之前,通过运行以下命令来测试您的replace()命令是很有帮助的:

代码语言:javascript
复制
select replace(sql, ...) from SQLITE_MASTER where name = 'child' and type = 'table';
票数 7
EN

Stack Overflow用户

发布于 2021-05-01 17:20:30

正如@Daniel Vassallo所说,你不能这样做。您必须使用的代码如下所示:

给出表:

代码语言:javascript
复制
CREATE TABLE child( 
id INTEGER PRIMARY KEY, 
parent_id INTEGER, 
description TEXT);

我假设您想要添加以下Foreignk密钥:

代码语言:javascript
复制
FOREIGN KEY (parent_id) REFERENCES parent(id);

因此,我将基于该表创建一个临时表,然后将创建一个新表作为第一个表,但使用外键,最后将临时表的数据添加到其中:

代码语言:javascript
复制
CREATE TEMPORARY TABLE temp AS
SELECT 
    id,
    parent_id,
    description
FROM child;

DROP TABLE child;

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

INSERT INTO child
 (  id,
    parent_id,
    description)
SELECT
    id,
    parent_id,
    description
FROM temp;
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1884818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档