我需要在SQLite数据库的某些表中重命名一些列。我知道以前在stackoverflow上也曾问过类似的问题,但这通常是针对SQL的,没有提到SQLite的情况。
从ALTER TABLE的SQLite文档中,我发现不可能“轻松”地执行此操作(即,单个ALTER TABLE语句)。
我想知道有人知道使用SQLite做这种事情的通用SQL方法。
我需要在SQLite数据库的某些表中重命名一些列。我知道以前在stackoverflow上也曾问过类似的问题,但这通常是针对SQL的,没有提到SQLite的情况。
从ALTER TABLE的SQLite文档中,我发现不可能“轻松”地执行此操作(即,单个ALTER TABLE语句)。
我想知道有人知道使用SQLite做这种事情的通用SQL方法。
Answers:
这已在2018-09-15(3.25.0)中修复
增强
ALTER TABLE
命令:
- 添加对使用
ALTER TABLE
table 重命名表中的列的支持RENAME COLUMN oldname TO newname
。- 修复表重命名功能,以便它还可以在触发器和视图中更新对重命名表的引用。
您可以在下面找到记录的新语法 ALTER TABLE
该
RENAME COLUMN TO
语法将表table-name的列名更改为new-column-name。在表定义本身内以及在所有引用该列的索引,触发器和视图内,都更改了列名。如果列名更改将导致触发器或视图中的语义歧义,则RENAME COLUMN
失败失败并显示错误,并且不应用任何更改。
图片来源: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;
在撰写本文时,Android的API 27正在使用SQLite软件包版本3.19。
根据Android当前使用的版本以及SQLite的3.25.0版本中的此更新,我想您需要等待一段时间(大约API 33),然后才能将此功能添加到Android中。
而且,即使那样,如果您需要支持API 33之前的任何版本,则将无法使用它。
database.execSQL("ALTER TABLE content RENAME COLUMN archiveCount TO dismissCount")
。COLUM以红色高亮显示,表示达到预期,得到了'COLUMN'。不幸的是,Android仍在SQLite 3.19版本上,这就是为什么它对我不起作用的原因。
假设您有一个表,需要将“ 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;
最后,放下旧桌子。
DROP TABLE tmp_table_name;
将所有内容包装在BEGIN TRANSACTION;
和COMMIT;
中可能也是一个好主意。
.schema
命令非常适合显示CREATE TABLE
构成现有表的语句。您可以获取其输出,根据需要进行修改,然后执行以创建新表。该命令还显示CREATE INDEX
创建索引的必要命令,该索引应涵盖Thomas的关注点。当然,请务必在更改任何内容之前运行此命令。
到处逛逛,我发现了这个名为(Linux | Mac | Windows)的多平台图形工具 DB Browser for SQLite的,它实际上允许人们以一种非常用户友好的方式重命名列!
编辑 修改表格| 选择表格| 编辑字段。点击一下!瞧!
但是,如果有人想分享一种编程方式来做到这一点,我将很高兴知道!
确实没有任何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
参考如下:
更改表
SQLite支持ALTER TABLE的有限子集。SQLite中的ALTER TABLE命令允许用户重命名表或向现有表添加新列。无法重命名列,删除列或从表中添加或删除约束。
最近,我不得不在SQLite3中使用名为points的表进行此操作具有colidms 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;
希望对您有用!
引用sqlite文档:
SQLite支持ALTER TABLE的有限子集。SQLite中的ALTER TABLE命令允许用户重命名表或向现有表添加新列。无法重命名列,删除列或在表中添加或删除约束。
当然,您可以做的是,使用新的布局创建一个新表SELECT * FROM old_table
,然后用您将收到的值填充新表。
首先,这是让我大吃一惊的事情之一:重命名列需要创建一个全新的表并将数据从旧表复制到新表...
我登陆进行SQLite操作的GUI是Base。它有一个漂亮的Log窗口,显示所有已执行的命令。通过Base重命名一列会在日志窗口中填充必要的命令:
然后可以轻松地将它们复制并粘贴到您可能需要的位置。对我来说, ActiveAndroid迁移文件。同样令人高兴的是,复制的数据仅包含SQLite命令,而不包含时间戳等。
希望可以节省一些时间。
BEGIN TRANSACTION;
,并COMMIT;
通过自身的线条,如ActiveAndroid把手。
情况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;
步骤2:现在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表。请记住,您还需要在新表上重新创建任何索引,查看器或触发器。
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");
如前所述,有一个工具SQLite数据库浏览器可以做到这一点。幸运的是,该工具保留了用户或应用程序执行的所有操作的日志。这样做一次并查看应用程序日志,您将看到所涉及的代码。复制查询并根据需要粘贴。为我工作。希望这可以帮助
可以选择使用更简单,更快速的过程进行某些更改,这些更改不会以任何方式影响磁盘上的内容。以下更简单的过程适用于删除CHECK或FOREIGN KEY或NOT NULL约束,重命名列或在列上添加或删除或更改默认值。
开始交易。
运行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中找到的旧架构版本号大1。
使用PRAGMA writable_schema = OFF禁用模式编辑。
(可选)运行PRAGMA integrity_check以验证架构更改是否不会损坏数据库。
提交从上面的步骤1开始的事务。
一种选择是,如果需要在紧急情况下完成操作,并且初始列是使用默认值创建的,则创建所需的新列,将内容复制到该列,然后基本上“放弃”旧列(保留该列)目前,但您只是不使用/更新它,等等)
例如:
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创建的,但没有默认值,那么以后忽略它的插入操作可能会失败),但是如果它只是一个一次性表,那么折衷可能是可以接受的。否则,请使用此处提到的其他答案之一,或使用允许重命名列的其他数据库。
从版本2018-09-15(3.25.0)开始,sqlite支持重命名列
sqlite3 yourdb .dump> /tmp/db.txt
编辑/tmp/db.txt更改创建行中的列名称
sqlite2 yourdb2 </tmp/db.txt
mv /移动yourdb2 yourdb