【问题标题】:set the default value of the new column to a value of an existing column after altering table更改表后将新列的默认值设置为现有列的值
【发布时间】:2021-06-07 14:21:11
【问题描述】:

我有一个名为“users”的表。

id 姓名 1 个插孔 2丽莎

我想添加一个新列并将其默认值设置为“id”列的值。

ALTER TABLE users ADD COLUMN user_index INTEGER NOT NULL DEFAULT id;

因为 DEFAULT 关键字只接受常量值,所以上面的代码不起作用。
那么,如何将新列的默认值设置为“id”列的值?

【问题讨论】:

  • 研究使用触发器。
  • 为什么要在表中出现两次相同的列?

标签: android sqlite android-studio android-sqlite alter-table


【解决方案1】:

这不能仅使用ALTER 语句来完成。我建议在事务中执行更改和副本,其中副本看起来像:

UPDATE tableName SET user_index = id;

【讨论】:

    【解决方案2】:

    相信下面的demo SQL会做你想做的。

    /*
        Create and populate inital table
    */
    DROP TRIGGER IF EXISTS set_user_index_as_id;
    DROP TABLE IF EXISTS users; -- Note will drop the trigger
    CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY, `name` TEXT);
    INSERT INTO users (`name`) VALUES('jack'),('lisa');
    -- Show all columns of all rows of the initial table
    SELECT * FROM users;
    -- Add the new column with default value of -1 (should not interfere with id assuming it is never -1)
    
    
    -- ONE-OFF SCHEMA CHANGE
    -- Note sets default for rows previously added to default
    ALTER TABLE users ADD COLUMN user_index INTEGER NOT NULL DEFAULT -1;
    -- Show all columns of all rows after the alter
    SELECT * FROM users;
    -- Add the trigger to adjust the user_index value whenever a row is inserted
    CREATE TRIGGER IF NOT EXISTS set_user_index_as_id AFTER INSERT ON users 
        BEGIN
            -- update rows that have not been updated i.e. user_index is -1 
            --    (so will adjust the original rows)
            UPDATE users SET user_index = id WHERE user_index = -1;
        END
    ;
    
    
    -- Add some more rows (i.e.test the above)
    INSERT INTO users ('name') VALUES('fred'),('mary');
    -- Show Show all columns of all rows after the inserts
    SELECT * FROM users;
    

    这会将默认值设置为 -1(假设 id 永远不会是 -1,它可能是另一个值,id 永远不会是那个值)当 ALTERing 表添加列时。然后添加一个 TRIGGER,每当插入新行时,它将更新 user_index 列中具有 -1 的任何行与 id 列的值相同。

    • 因为所有带有 -1 的行都会更新,所以添加触发器后的第一个插入将更新任何先前插入的行(默认值追溯应用于旧行)

    • 注意以上是一个演示,旨在重新运行,因此是 DROP 语句。

    运行显示进度的查询时,是:-

    初始插入后

    改变之后

    新插入之后


    以上假设 id 是 rowid 的别名(称为 AUTOINCREMENT),因此行是单调递增的(从 1 增加到 2 到 3 ....)。

    但是,假设前两行的 id 值为 10 和 50,然后是新的 51 和 52 行。将应用这些乱序值。一个和上面很相似的测试,只是把第一个insert改成INSERT INTO users VALUES(10,'jack'),(50,'lisa'); 正如预期的那样,最终结果为:-

    【讨论】:

      猜你喜欢
      • 2011-04-18
      • 1970-01-01
      • 2014-06-01
      • 1970-01-01
      • 2011-10-11
      • 2016-08-03
      • 1970-01-01
      • 1970-01-01
      • 2019-08-17
      相关资源
      最近更新 更多