Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何向现有SQLite表添加外键?_Sql_Sqlite_Foreign Keys_Ddl - Fatal编程技术网

如何向现有SQLite表添加外键?

如何向现有SQLite表添加外键?,sql,sqlite,foreign-keys,ddl,Sql,Sqlite,Foreign Keys,Ddl,我有下表: CREATE TABLE child( id INTEGER PRIMARY KEY, parent_id INTEGER, description TEXT); 如何在parent\u id上添加外键约束?假设启用了外键 大多数示例假设您正在创建表-我想将约束添加到现有的表中。您不能。 尽管将外键添加到表中的SQL-92语法如下所示: ALTER TABLE child ADD CONSTRAINT fk_child_parent

我有下表:

CREATE TABLE child( 
  id INTEGER PRIMARY KEY, 
  parent_id INTEGER, 
  description TEXT);
如何在
parent\u id
上添加外键约束?假设启用了外键


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

您不能。

尽管将外键添加到表中的SQL-92语法如下所示:

ALTER TABLE child ADD CONSTRAINT fk_child_parent
                  FOREIGN KEY (parent_id) 
                  REFERENCES parent(id);
CREATE TABLE child ( 
    id           INTEGER PRIMARY KEY, 
    parent_id    INTEGER, 
    description  TEXT,
    FOREIGN KEY (parent_id) REFERENCES parent(id)
);
SQLite不支持
ALTER TABLE
命令()的
ADD CONSTRAINT
变体

因此,在sqlite 3.6.1中添加外键的唯一方法是在
CREATE TABLE
期间,如下所示:

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

不幸的是,您必须将现有数据保存到临时表中,删除旧表,使用FK约束创建新表,然后将数据从临时表中复制回来。()

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

首先,创建不带父\u id的表:

CREATE TABLE child( 
  id INTEGER PRIMARY KEY,  
  description TEXT);
然后,更改表格:

ALTER TABLE child ADD COLUMN parent_id INTEGER REFERENCES parent(id);

如果您正在使用Firefox插件sqlite管理器,您可以执行以下操作:

不必再次删除和创建表,只需像这样修改即可

在“列”文本框中,右键单击列出的最后一个列名以打开关联菜单,然后选择“编辑列”。 请注意,如果表定义中的最后一列是主键,则必须首先添加新列,然后编辑新列的列类型,以便添加外键定义。 在“列类型”框中,添加逗号和

FOREIGN KEY (parent_id) REFERENCES parent(id)
数据类型后的定义。 单击“更改”按钮,然后单击“危险操作”对话框上的“是”按钮

参考: 请检查

SQLite直接支持的唯一模式更改命令是 如上所示的“重命名表格”和“添加列”命令。然而, 应用程序可以对表的格式进行其他任意更改 使用简单的操作序列。使其具有任意性的步骤 某些表X的架构设计更改如下:

ALTER TABLE child ADD CONSTRAINT fk_child_parent
                  FOREIGN KEY (parent_id) 
                  REFERENCES parent(id);
CREATE TABLE child ( 
    id           INTEGER PRIMARY KEY, 
    parent_id    INTEGER, 
    description  TEXT,
    FOREIGN KEY (parent_id) REFERENCES parent(id)
);
  • 如果启用了外键约束,请使用PRAGMA禁用它们 外键=关闭
  • 开始一项交易
  • 记住与关联的所有索引和触发器的格式 表X。以下第8步需要此信息。单程 这样做是为了运行如下查询:选择类型,sql自 sqlite_master,其中tbl_name='X'
  • 使用CREATE TABLE可在 表X的所需修订格式。确保名称“new_X” 当然,不会与任何现有表名冲突
  • 使用类似于:INSERT的语句将内容从X传输到新的_X 进入新的\u X选择。。。从X
  • 删除旧表X:删除表X
  • 使用:ALTER TABLE new_X RENAME to X将new_X的名称更改为X
  • 使用“创建索引”和“创建触发器”来重建索引和 与表X关联的触发器。可能使用 以上步骤3中保存的触发器和索引作为指南,使 根据变更情况进行适当的变更
  • 如果任何视图以受影响的方式参考表X 架构更改,然后使用drop VIEW删除这些视图并重新创建 它们需要进行任何必要的更改以适应模式 使用创建视图进行更改
  • 如果最初启用了外键约束,则运行PRAGMA 外键检查以验证架构更改没有中断 任何外键约束
  • 提交在步骤2中启动的事务
  • 如果最初启用了外键约束,请重新启用它们 现在
  • 上述程序是完全通用的,即使 模式更改导致表中存储的信息更改。所以 上述完整程序适用于删除列, 更改列的顺序,添加或删除唯一约束 或主键,添加CHECK或外键或NOTNULL约束, 或者更改列的数据类型,例如


    首先在子表
    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
    

    基本上你不能,但你可以绕过这种情况

    将外键约束添加到现有表的正确方法是使用以下命令

    db.execSQL("alter table child add column newCol integer REFERENCES parent(parent_Id)");
    
    然后将父Id数据复制到newCol,然后删除父Id列。
    因此,不需要临时表。

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

    对于您的具体示例:

    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
    
    或者更一般地说:

    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 replace(sql, ...) from SQLITE_MASTER where name = 'child' and type = 'table';
    
    您可以尝试以下方法:

    ALTER TABLE [Child] ADD COLUMN column_name INTEGER REFERENCES parent_table_name(column_id);
    

    如果对sqlite使用Db Browser,那么修改表就很容易了。您可以在现有表中添加外键,而无需编写查询

    • 在数据库浏览器中打开数据库
    • 只需在表上单击鼠标右键,然后单击“修改”
    • 在那里滚动到外键列
    • 双击要更改的字段
    • 然后选择表及其字段并单击“确定”

    就这样。您已成功将外键添加到现有表中。

    为现有SQLLite表创建外键:

    对于SQLLite,没有直接的方法可以做到这一点。运行下面的查询以重新执行
    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;