首页 文章

如何重命名SQLite数据库表中的列?

提问于
浏览
255

我需要在SQLite数据库的某些表中重命名几列 . 我知道之前已经在stackoverflow上询问了similar question,但它一般用于SQL,并且没有提到SQLite的情况 .

ALTER TABLE的SQLite文档中,我认为不可能做这样的事情"easily"(即单个ALTER TABLE语句) .

我想知道有人知道用SQLite做这种事情的通用SQL方式 .

13 回答

  • 13

    四处搜索,我发现这个名为DB Browser for SQLite的多平台(Linux | Mac | Windows)图形工具实际上允许用户以非常友好的方式重命名列!

    编辑|修改表|选择表|编辑字段 . 点击!瞧!

    但是,如果有人想分享一种程序化的方式,我很高兴知道!

  • 53

    首先,这是让我惊讶的事情之一:重命名列需要创建一个全新的表并将数据从旧表复制到新表...

    我已经登陆进行SQLite操作的GUI是Base . 它有一个漂亮的日志窗口,显示已执行的所有命令 . 通过Base重命名列会使用必要的命令填充日志窗口:

    Base log window

    然后可以轻松地将它们复制并粘贴到您可能需要的位置 . 对我来说,这是一个ActiveAndroid迁移文件 . 同样好的一点是,复制的数据只包含SQLite命令,而不包括时间戳等 .

    希望这能节省一些人的时间 .

  • 2

    假设您有一个表,需要将“colb”重命名为“col_b”:

    首先重命名旧表:

    ALTER TABLE orig_table_name RENAME TO tmp_table_name;
    

    然后根据旧表创建新表,但使用更新的列名:

    CREATE TABLE orig_table_name (
      col_a INT
    , col_b INT
    );
    

    然后从原始表中复制内容 .

    INSERT INTO orig_table_name(col_a, col_b)
    SELECT col_a, colb
    FROM tmp_table_name;
    

    最后,放下旧 table .

    DROP TABLE tmp_table_name;
    

    将所有这些包装在 BEGIN TRANSACTION; 和_355105中也可能是一个好主意 .

  • 7

    From the official documentation

    A simpler and faster procedure 可以选择用于某些不会以任何方式影响磁盘内容的更改 . 以下更简单的过程适用于删除CHECK或FOREIGN KEY或NOT NULL约束, renaming columns ,或添加或删除或更改列上的默认值 .

    • 开始交易 .

    • 运行PRAGMA schema_version以确定当前架构版本号 . 下面的步骤6将需要此号码 .

    • 使用PRAGMA writable_schema = ON激活模式编辑 .

    • 运行UPDATE语句以更改sqlite_master表中表X的定义:UPDATE sqlite_master SET sql = ... WHERE type ='table'AND name ='X';

    警告:如果更改包含语法错误,则对此类sqlite_master表进行更改将导致数据库损坏且无法读取 . 建议在将UPDATE语句用于包含重要数据的数据库之前,对单独的空白数据库进行仔细测试 .

    • 如果对表X的更改也影响其他表或索引或触发器是模式中的视图,则运行UPDATE语句以修改其他表索引和视图 . 例如,如果列名称发生更改,则必须修改引用该列的所有FOREIGN KEY约束,触发器,索引和视图 .

    警告:再次,如果更改包含错误,则对此类sqlite_master表进行更改将导致数据库损坏且无法读取 . 在运行此过程之前,在包含重要数据的数据库上使用它并/或制作重要数据库的备份副本之前,请在单独的测试数据库上仔细测试整个过程 .

    • 使用PRAGMA schema_version = X增加架构版本号,其中X比上面步骤2中找到的旧架构版本号多一个 .

    • 使用PRAGMA writable_schema = OFF禁用模式编辑 .

    • (可选)运行PRAGMA integrity_check以验证架构更改是否损坏数据库 .

    • 提交上面步骤1中启动的事务 .

  • 2

    如前所述,有一个工具SQLite数据库浏览器,它执行此操作 . Lyckily,这个工具记录了用户或应用程序执行的所有操作 . 执行此操作并查看应用程序日志,您将看到所涉及的代码 . 根据需要复制查询和粘贴 . 为我工作 . 希望这可以帮助

  • 1

    使用所需的列名创建一个新列:COLNew .

    ALTER TABLE {tableName} ADD COLUMN COLNew {type};
    

    将旧列COLOld的内容复制到新列COLNew .

    INSERT INTO {tableName} (COLNew) SELECT {COLOld} FROM {tableName}
    

    注意:上面一行需要括号 .

  • 3

    最近我不得不在SQLite3中使用一个名为 points 的表,其中包含colunms id, lon, lat . 错误的是,当导入表时,纬度的值存储在 lon 列中,反之亦然,因此明显的修复方法是重命名这些列 . 所以诀窍是:

    create table points_tmp as select id, lon as lat, lat as lon from points;
    drop table points;
    alter table points_tmp rename to points;
    

    我希望这对你有用!

  • -3

    引用sqlite documentation

    SQLite支持有限的子集更改表 . SQLite中的ALTER TABLE命令允许用户重命名表或向现有表添加新列 . 无法重命名列,删除列,或从表中添加或删除约束 .

    您当然可以做的是,使用新布局创建一个新表 SELECT * FROM old_table ,并使用您将收到的值填充新表 .

  • 2

    将表格列<id>更改为<_id>

    String LastId = "id";
    
        database.execSQL("ALTER TABLE " + PhraseContract.TABLE_NAME + " RENAME TO " + PhraseContract.TABLE_NAME + "old");
        database.execSQL("CREATE TABLE " + PhraseContract.TABLE_NAME
        +"("
                + PhraseContract.COLUMN_ID + " INTEGER PRIMARY KEY,"
                + PhraseContract.COLUMN_PHRASE + " text ,"
                + PhraseContract.COLUMN_ORDER  + " text ,"
                + PhraseContract.COLUMN_FROM_A_LANG + " text"
        +")"
        );
        database.execSQL("INSERT INTO " +
                PhraseContract.TABLE_NAME + "("+ PhraseContract.COLUMN_ID +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +")" +
                " SELECT " + LastId +" , "+ PhraseContract.COLUMN_PHRASE + " , "+ PhraseContract.COLUMN_ORDER +" , "+ PhraseContract.COLUMN_FROM_A_LANG +
                " FROM " + PhraseContract.TABLE_NAME + "old");
        database.execSQL("DROP TABLE " + PhraseContract.TABLE_NAME + "old");
    
  • 11

    sqlite3 yourdb .dump> /tmp/db.txt
    编辑/tmp/db.txt更改创建行中的列名
    sqlite2 yourdb2 </tmp/db.txt
    mv / move yourdb2 yourdb

  • 426

    一个选项,如果您需要在紧要关头完成,并且如果您的初始列是使用默认创建的,则创建所需的新列,将内容复制到其中,并基本上“放弃”旧列(它保持不变现在,但你只是不使用/更新它等)

    例如:

    alter table TABLE_NAME ADD COLUMN new_column_name TYPE NOT NULL DEFAULT '';
    update TABLE_NAME set new_column_name = old_column_name;
    update TABLE_NAME set old_column_name = ''; -- abandon old column, basically
    

    这留下了一个列(如果它是使用NOT NULL创建但没有默认值,那么将来忽略它的插入可能会失败),但如果它只是一次性表,那么权衡可能是可以接受的 . 否则,请使用此处提到的其他答案之一,或使用允许重命名列的其他数据库 .

  • 51

    这只是用2018-09-15 (3.25.0)修复的

    增强ALTER TABLE命令:使用ALTER TABLE表RENAME COLUMN oldname TO newname添加对表中列重命名的支持 . 修复表重命名功能,以便它还更新对触发器和视图中重命名的表的引用 .

    您可以在ALTER TABLE下找到新的语法

    RENAME COLUMN TO语法将table table-name的列名更改为new-column-name . 列名称在表定义本身内以及引用该列的所有索引,触发器和视图中都会更改 . 如果列名称更改将导致触发器或视图中出现语义歧义,则RENAME COLUMN将失败并显示错误,并且不会应用任何更改 .

    enter image description here
    图片来源:https://www.sqlite.org/images/syntax/alter-table-stmt.gif

  • 18

    虽然没有ALTER COLUMN,但如果您只想重命名列,删除NOT NULL约束或更改数据类型,则可以使用以下命令集:

    注意:这些命令可能会损坏您的数据库,因此请确保您有备份

    PRAGMA writable_schema = 1;
    UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';
    PRAGMA writable_schema = 0;
    

    您需要关闭并重新打开连接或清空数据库以将更改重新加载到架构中 .

    例如:

    Y:\> sqlite3 booktest  
    SQLite version 3.7.4  
    Enter ".help" for instructions  
    Enter SQL statements terminated with a ";"  
    sqlite> create table BOOKS ( title TEXT NOT NULL, publication_date TEXT NOT NULL);  
    sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
    Error: BOOKS.publication_date may not be NULL  
    sqlite> PRAGMA writable_schema = 1; 
    sqlite> UPDATE SQLITE_MASTER SET SQL = 'CREATE TABLE BOOKS ( title TEXT NOT NULL, publication_date TEXT)' WHERE NAME = 'BOOKS';  
    sqlite> PRAGMA writable_schema = 0;  
    sqlite> .q  
    
    Y:\> sqlite3 booktest  
    SQLite version 3.7.4  
    Enter ".help" for instructions  
    Enter SQL statements terminated with a ";"  
    sqlite> insert into BOOKS VALUES ("NULLTEST",null);  
    sqlite> .q
    

    REFERENCES FOLLOW:


    pragma writable_schema
    启用此pragma时,SQLITE_MASTER表可以使用普通的UPDATE,INSERT和DELETE语句更改数据库 . 警告:滥用此pragma很容易导致数据库文件损坏 .

    alter table
    SQLite支持ALTER TABLE的有限子集 . SQLite中的ALTER TABLE命令允许用户重命名表或向现有表添加新列 . 无法重命名列,删除列,或从表中添加或删除约束 .

    ALTER TABLE SYNTAX

相关问题