【发布时间】:2009-11-11 16:25:51
【问题描述】:
这看起来很简单:我想在 SQLite 表中复制一行:
INSERT INTO table SELECT * FROM table WHERE rowId=5;
如果没有明确的唯一列声明,该语句将起作用,但表的第一列声明为rowID INTEGER NOT NULL PRIMARY KEY。有没有什么方法可以在不知道表架构的情况下创建一个像上面那样的简单语句(除了第一列)?
【问题讨论】:
这看起来很简单:我想在 SQLite 表中复制一行:
INSERT INTO table SELECT * FROM table WHERE rowId=5;
如果没有明确的唯一列声明,该语句将起作用,但表的第一列声明为rowID INTEGER NOT NULL PRIMARY KEY。有没有什么方法可以在不知道表架构的情况下创建一个像上面那样的简单语句(除了第一列)?
【问题讨论】:
这可以使用 * 语法来完成,而无需知道表的架构(除了主键的名称)。诀窍是使用“CREATE TABLE AS”语法创建一个临时表。
在此示例中,我假设存在一个名为“src”的现有填充表,其中包含一个名为“id”的 INTEGER PRIMARY KEY,以及其他几个列。要复制“src”的行,请在 SQLite3 中使用以下 SQL:
CREATE TEMPORARY TABLE tmp AS SELECT * FROM src;
UPDATE tmp SET id = NULL;
INSERT INTO src SELECT * FROM tmp;
DROP TABLE tmp;
上面的例子复制了表“src”的所有行。要仅复制所需的行,只需将 WHERE 子句添加到第一行。此示例有效,因为表“tmp”没有主键约束,但“src”有。将 NULL 主键插入 src 会导致它们被赋予自动生成的值。
来自 sqlite 文档:http://www.sqlite.org/lang_createtable.html
“CREATE TABLE ... AS SELECT”语句根据 SELECT 语句的结果创建并填充数据库表。使用 CREATE TABLE AS 创建的表没有 PRIMARY KEY 也没有任何类型的约束。
如果你想变得更花哨,你可以添加一个触发器来更新第三个表,该表将旧主键映射到新生成的主键。
【讨论】:
没有。您需要知道表的架构才能正确编写插入语句。
您需要能够以以下形式编写语句:
insert into Table (column1, column2, column3)
select column1, column2, column3
from OtherTable
where rowId = 5
【讨论】:
好吧,由于我无法按照我想要的方式执行此操作,我求助于使用隐式行 ID,它与我明确定义的 rowId 列具有相同的名称,所以现在我可以使用我拥有的查询在问题中,它将使用新的 rowId 插入所有数据。为了让程序的其余部分正常工作,我只是将SELECT * FROM table 更改为SELECT rowId,* FROM table,一切都很好。
【讨论】:
绝对没有办法做到这一点。主键声明意味着该字段是唯一的。你不能有一个非唯一的PK。无法在同一个表中创建具有现有 PK 的行。
【讨论】: