SQLite:在保留数据的同时,将具有主键的列添加到现有表

时间:2015-02-02 15:47:11

标签: database sqlite unique-constraint

在SQLite的上下文中。

我有一个现有的表,当前填充了大量的数据行。

我正在尝试向此表添加新的主键列,同时保留原始数据。

如下所示,我尝试了以下

  1. 将新列添加到现有表(Id INTEGER)。
  2. 更改现有表的名称。
  3. 创建一个包含新主键(Id INTEGER PRIMARY KEY)的新表。
  4. 将重命名表中的所有数据插入到新创建的表中。
  5. 删除重命名的表格。
  6. 我认为这会起作用的原因是因为根据SQlite文档,

      

    声明为INTEGER PRIMARY KEY的列将自动增量。

    但是我收到以下错误。

    ErrorCode : 19
    Message   : constraint failed
    UNIQUE constraint failed: Person.Id
    Result    : Constraint
    

    这是我的代码。

    --Add a new column to the existing table(Id INT).
    ALTER TABLE [Person]
    ADD Id INTEGER;
    
    --Change the name of the existing table.
    ALTER TABLE [Person] RENAME TO Person_temp;
    
    --Create a new table which includes the new PK.
    CREATE TABLE Person(
        Id INTEGER PRIMARY KEY,
        FirstName nvarchar(100) NULL,
        LastName nvarchar(100) NULL
    );
    
    --Insert all data from the renamed table into the new table.
    INSERT INTO Person SELECT * FROM Person_temp;
    
    --Drop the renamed table.
    DROP TABLE Person_temp;
    

    任何人都可以友善地发光吗?

2 个答案:

答案 0 :(得分:1)

看起来您的Id列在每一行中都不包含唯一值。由于您刚刚添加了列,因此每行将具有相同的值。

插入新行时,自动增量可以提供帮助。 (您不必选择max(id),并插入id = max + 1的新行)。它不会自动填充现有的数据表。

SQLite已经有了一个可以满足您需求的列。它被称为ROWID。尝试使用它而不是将其与您的Id列重复。

答案 1 :(得分:1)

由于您未在插入查询中声明列名,因此列顺序取决于创建/添加的顺序。尝试指定列名称。无论如何,这通常都是一种很好的做法

--Insert all data from the renamed table into the new table.
INSERT INTO Person(Id, FirstName, LastName) SELECT Id, FirstName, LastName FROM Person_temp;

顺便说一句,您可能不需要在第一个表格中添加Id列:

--Insert all data from the renamed table into the new table.
INSERT INTO Person(FirstName, LastName) SELECT FirstName, LastName FROM Person_temp;

Id的隐式空值将被自动增量替换