更改表后将新列的默认值设置为现有列的值

问题描述

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

id   name 
1    jack
2    lisa

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

import "./styles.css";
import styled from "styled-components";

const TreeNode = styled.li`
  &:before {
    font-family: "Font Awesome 5 Free";
    margin-right: 10px;
    font-weight: 600;
    content: ${(props) => String.fromCharCode(props.icon,16)};
    color: ${(props) => props.iconcolor};
  }`;

export default function App() {
  return (
    <ul>
      <TreeNode icon="f004" iconcolor="red">
        Node Will Go Here!
      </TreeNode>
    </ul>
  );
}

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

解决方法

仅使用 ALTER 语句无法做到这一点。我建议在交易中执行更改和副本,其中副本看起来像:

UPDATE tableName SET user_index = id;
,

我相信下面的演示 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 永远不会是该值)。然后添加一个 TRIGGER,每当插入新行时,它将更新 user_index 列中具有 -1 的所有行,使其与 id 列的值相同。

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

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

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

初始插入后

enter image description here

改变之后

enter image description here

在新插入之后

enter image description here


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

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

enter image description here