我有一个包含 name
、qty
、rate
列的表。现在我需要在 name
和 qty
列之间添加一个新列 COLNew
。如何在两列之间添加新列?
你有两个选择。首先,您可以简单地添加一个包含以下内容的新列:
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
其次,更复杂,但实际上会将列放在您想要的位置,将创建具有缺失列和临时新名称的新表:
CREATE TABLE {tempNewTableName} (name TEXT, COLNew {type} DEFAULT {defaultValue}, qty INTEGER, rate REAL);
并用旧数据填充它:
INSERT INTO {tempNewTableName} (name, qty, rate) SELECT name, qty, rate FROM OldTable;
然后删除旧表:
DROP TABLE OldTable;
然后将新表重命名为 OldTable 的名称:
ALTER TABLE {tempNewTableName} RENAME TO OldTable;
我更喜欢第二个选项,因为它可以让您在需要时完全重命名所有内容。
您无需在 SQL 中的其他列之间添加列,您只需添加它们。它们的放置位置完全取决于 DBMS。确保列以正确顺序出现的正确位置是当您 select
列时。
换句话说,如果您希望它们按 {name,colnew,qty,rate}
的顺序排列,您可以使用:
select name, colnew, qty, rate from ...
对于 SQLite,您需要使用 alter table
,例如:
alter table mytable add column colnew char(50)
SELECT * FROM mytable
?
select *
的用例。对于想要发现表的程序来说,它有时很方便,但对于绝大多数用途,您应该明确指定您想要的内容以及您想要的顺序。
您可以使用查询添加新列
ALTER TABLE TableName ADD COLUMN COLNew CHAR(25)
但它将在最后添加,而不是在现有列之间。
SQLite 具有有限的 ALTER TABLE 支持,您可以使用它来将列添加到表的末尾或更改表的名称。
如果要对表结构进行更复杂的更改,则必须重新创建表。您可以将现有数据保存到临时表中,删除旧表,创建新表,然后将数据从临时表中复制回来。
例如,假设您有一个名为“t1”的表,其列名为“a”和“c”,并且您希望从该表中插入列“b”。以下步骤说明了如何做到这一点:
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,c);
INSERT INTO t1_backup SELECT a,c FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b, c);
INSERT INTO t1 SELECT a,c FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;
现在您已准备好插入新数据,如下所示:
UPDATE t1 SET b='blah' WHERE a='key'
INSERT INTO t1 SELECT a,c FROM t1_backup;
行导致错误:“表 t1 有 3 列,但提供了 2 个值:INSERT INTO t1 SELECT a,c FROM t1_backup;”。正确的行应该是 INSERT INTO t1 (a,c) SELECT a,c FROM t1_backup;
ALTER TABLE {tableName} ADD COLUMN COLNew {type};
UPDATE {tableName} SET COLNew = {base on {type} pass value here};
此更新需要处理空值,根据需要输入默认值。与您的情况一样,您需要调用 SELECT
查询,您将获得列的顺序,正如 paxdiablo 已经说过的:
SELECT name, colnew, qty, rate FROM{tablename}
在我看来,你的列名从光标中获取值:
private static final String ColNew="ColNew";
String val=cursor.getString(cursor.getColumnIndex(ColNew));
因此,如果索引更改,您的应用程序将不会遇到任何问题。
这是一种安全的方式,否则,如果您使用 CREATE temptable
或 RENAME table
或 CREATE
,如果不小心处理(例如在您的事务发生的情况下),数据丢失的可能性很高电池电量耗尽时。
我遇到了同样的问题,并且如评论中所述,在接受的答案中提出的第二种方法在处理外键时可能会出现问题。
我的解决方法是将数据库导出到一个 sql 文件,确保 INSERT 语句包含列名。我使用 DB Browser for SQLite 来做这件事,它有一个方便的功能。之后,您只需编辑 create table 语句并将新列插入您想要的位置并重新创建数据库。
在 *nix 之类的系统中,只是类似于
cat db.sql | sqlite3 database.db
我不知道这对于非常大的数据库有多可行,但它适用于我的情况。
我很少为 11 岁的问题添加答案。也就是说,有很多选票的答案有一段误导性的代码。我说误导是因为我尝试过但没有成功。这是我引用的代码行。
ALTER TABLE {tableName} RENAME TO TempOldTable
这是我第一次尝试将列添加到已创建的数据库表中时尝试的行。它失败了,但为什么可能是一个更好的问题。这里的任何方式都是失败的代码行。
Dim tb As String = "IncomeTable"
Dim sqlCmd As String = "$ALTER TABLE" '{tb}' "ADD COLUMN itNumVisit INTEGER"
所以这是在我的例子中添加一个新列的最终代码,它是一个 INTEGER 类型。
Private Sub btnCopyTable_Click(sender As Object, e As EventArgs) Handles btnCopyTable.Click
Dim sqlCmd As String = "ALTER TABLE IncomeTable ADD COLUMN itNumVisit INTEGER"
Try
Using conn As New SQLiteConnection($"Data Source = '{gv_dbName}';Version=3;")
conn.Open()
Using cmd As New SQLiteCommand(sqlCmd, conn)
cmd.ExecuteNonQuery()
End Using
End Using
Catch ex As Exception
MsgBox("It Failed")
End Try
End Sub
请注意,STRING sqlCmd 都是一个字符串。以防万一有人尝试了接受的答案!
PRAGMA foreign_keys = ON;
(参见 sqlite.org/foreignkeys.html#fk_enable)