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

我需要重命名SQLite数据库中一些表中的一些列。 我知道之前在stackoverflow上已经问过类似的问题,但它一般是用于SQL的,SQLite的情况没有提到

ALTER TABLE的SQLite文档中,我收集到不可能“轻松”地做这样的事情(即一个ALTER TABLE语句)。

我想知道有人知道一个通用的SQL方法做这样的事情与SQLite。

207340 次浏览

引用sqlite文档:

SQLite支持的有限子集 ALTER TABLE。ALTER TABLE命令 在SQLite中允许用户重命名 表或添加新列到 现有的表。不能重命名列、删除列或从表中添加或删除约束。 < / p >

当然,你能做的是,用新的布局SELECT * FROM old_table创建一个新表,并用你将收到的值填充新表。

深入研究后,我发现了这个多平台(Linux | Mac | Windows)图形化工具DB浏览器的SQLite,它实际上允许人们以一种非常用户友好的方式重命名列!

Edit | Modify Table |选中“Table | Edit Field”。点击点击!瞧!

然而,如果有人想分享一种程序化的方式来做这件事,我很乐意知道!

注意,从版本3.25.0发布于2018年9月开始,你现在可以使用ALTER TABLE重命名列

独创“造新掉旧表”下面的回答。


假设你有一个表,需要重命名“colb"以“col_b":

首先创建一个临时名称的新表,该名称基于旧表定义,但使用了更新的列名:

CREATE TABLE tmp_table_name (
col_a INT
, col_b INT
);

然后从原始表复制内容。

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

放下旧桌子。

DROP TABLE orig_table_name;

最后将临时表重命名为原来的表:

ALTER TABLE tmp_table_name RENAME TO orig_table_name;

不要忘记重新创建索引、触发器等。的文档给出了更全面的陷阱和注意事项。

将所有这些都包装在BEGIN TRANSACTION;COMMIT;中可能也是一个好主意。

虽然确实没有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

< >强引用:


编译指示writable_schema < br > 当打开此pragma时,数据库所在的SQLITE_MASTER表可以使用普通的UPDATE、INSERT和DELETE语句进行更改。警告:误用此pragma很容易导致数据库文件损坏 < p > alter table < br > SQLite支持ALTER TABLE的一个有限子集。SQLite中的ALTER TABLE命令允许用户重命名表或向现有表添加新列。不能重命名列、删除列或从表中添加或删除约束。< / p >

ALTER TABLE SYNTAX

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

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;

我希望这对你有用!

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

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

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

基本日志窗口

然后可以很容易地复制和粘贴到您可能需要的地方。对我来说,这是一个ActiveAndroid迁移文件。还有一个不错的地方,复制的数据只包括SQLite命令,不包括时间戳等。

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

sqlite3 yourdb .dump > /tmp/db.txt
编辑/tmp/db.txt在Create line
中修改列名 Sqlite2 yourdb2 </ tmp / db.txt < br > Mv /move yourdb2 yourdb

更改表列<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");

创建一个具有所需列名的新列:COLNew。

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

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

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

注:以上一行必须使用括号。

一种选择是,如果你需要在紧要时刻完成它,如果你的初始列是用默认创建的,那就创建你想要的新列,将内容复制到它,然后基本上“放弃”旧列(它仍然存在,但你只是不使用/更新它,等等)。

例:

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创建的,但没有默认值,那么未来的插入可能会忽略它),但如果它只是一个丢弃的表,那么折衷可能是可以接受的。否则,请使用这里提到的其他答案之一,或者使用允许重命名列的不同数据库。

来自官方文档

一个更简单快捷的程序可选地用于某些不以任何方式影响磁盘上内容的更改。以下更简单的过程适用于删除CHECK或FOREIGN KEY或NOT NULL约束,重命名列,或添加、删除或更改列上的默认值。

  1. 启动事务。

  2. 运行PRAGMA schema_version来确定当前的模式版本号。下面的第6步将需要这个数字。

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

  4. 使用UPDATE语句修改sqlite_master表X的定义:UPDATE sqlite_master SET sql=…WHERE type='table' AND name='X';

    警告:像这样对sqlite_master表进行更改,如果更改包含语法错误,将导致数据库损坏且不可读。建议在包含重要数据的数据库上使用UPDATE语句之前,在一个单独的空白数据库上仔细测试UPDATE语句

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

    警告:再次强调,对sqlite_master表进行这样的更改,如果更改包含错误,将导致数据库损坏且不可读。在将整个过程用于包含重要数据的数据库之前,请在单独的测试数据库上仔细测试它,并且/或在运行此过程之前对重要数据库进行备份

  6. 使用PRAGMA schema_version=X增加模式版本号,其中X比上面第2步中发现的旧模式版本号大1。

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

  8. (可选)执行PRAGMA integrity_check命令,验证模式更改没有破坏数据库。

  9. 提交上面第1步开始的事务。

这个问题刚刚被2018-09-15 (3.25.0)修复

增强ALTER TABLE命令:

  • 添加使用ALTER TABLERENAME COLUMN oldname TO newname重命名表中的列的支持。
  • 修复表重命名特性,以便在触发器和视图中更新对重命名表的引用。

你可以在ALTER TABLE下面找到新的语法文档

RENAME COLUMN TO语法将表table-name的column-name更改为new-column-name。在表定义本身以及引用该列的所有索引、触发器和视图中更改列名。如果更改列名将导致触发器或视图中的语义模糊,则RENAME COLUMN失败并报错,并且不应用任何更改。

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

例子:

CREATE TABLE tab AS SELECT 1 AS c;


SELECT * FROM tab;


ALTER TABLE tab RENAME COLUMN c to c_new;


SELECT * FROM tab;

db-fiddle.com demo


Android支持

截至撰写时,Android的API 27正在使用SQLite包3.19版本

基于Android正在使用的当前版本,这个更新将在SQLite的3.25.0版本中发布,我想说的是,在Android添加此支持之前,您需要等待(大约API 33)。

而且,即使这样,如果你需要支持任何比API 33更老的版本,你也不能使用这个。

从版本2018-09-15(3.25.0)开始 Sqlite支持重命名

的列

https://sqlite.org/changes.html

案例1:SQLite 3.25.0+

只有SQLite的3.25.0版本支持重命名列。如果你的设备满足这个要求,事情就很简单了。下面的查询可以解决你的问题:

ALTER TABLE "MyTable" RENAME COLUMN "OldColumn" TO "NewColumn";

案例2:SQLite旧版本

你必须遵循不同的方法来得到结果,这可能有点棘手

例如,如果你有一个这样的表:

CREATE TABLE student(Name TEXT, Department TEXT, Location TEXT)

如果您希望更改列Location的名称

步骤1:重命名原来的表:

ALTER TABLE student RENAME TO student_temp;

现在用正确的列名创建一个新表student:

CREATE TABLE student(Name TEXT, Department TEXT, Address TEXT)

步骤3:将数据从原表复制到新表:

INSERT INTO student(Name, Department, Address) SELECT Name, Department, Location FROM student_temp;

注意:上面的命令应该是一行。

步骤4:删除原表:

DROP TABLE student_temp;
通过这四个步骤,您可以手动更改任何SQLite表。 请记住,您还需要在新表上重新创建任何索引、查看器或触发器

需要重命名一些表中的一些列

另一种方法是使用多个SQLite3命令来“重命名”;一个列, 在“some"表,根据需要重复:

.output tmp


SELECT "ALTER TABLE """|| sqlite_master.name ||""" RENAME COLUMN old_name TO new_name;" FROM sqlite_master
WHERE type = "table" AND sqlite_master.name NOT LIKE 'sqlite_%';


.read tmp

< a href = " https://stackoverflow.com/questions/16160952/how-to-apply-a-sqlite-command-to-all-tables " > < / >来源