【问题标题】:Add a column with a default value to an existing table in postgresql将具有默认值的列添加到 postgresql 中的现有表
【发布时间】:2021-12-11 23:54:15
【问题描述】:

是否有一个 postgres 查询可以向现有表中添加一个新列,并自动为该表的所有行填充特定值,例如 "A1"仅一次,随着列的创建,我仍然可以将列的默认值设置为另一个值,比如说"B2"?

为了清楚起见,我正在寻找这样的东西:

给定my_table

name   |   work
------------------------
bob    |  fireman
carl   |  teacher
alice  |  policeman

我的查询

ALTER TABLE my_table 
ADD COLUMN description varchar(100) 
DEFAULT "B2"
COMMAND_I_D_WISH_TO_KNOW "A1";

my_table改成

name   |   work       | description
-------------------------------------
bob    |  fireman     | "A1"
carl   |  teacher     | "A1"
alice  |  policeman   | "A1"

这样如果之后我运行查询

INSERT INTO my_table(name, work)
VALUES karen, developer;

my_tables 变为

name   |   work       | description
-------------------------------------
bob    |  fireman     | "A1"
carl   |  teacher     | "A1"
alice  |  policeman   | "A1"
karen  |  developer   | "B2"

【问题讨论】:

    标签: sql postgresql ddl


    【解决方案1】:

    是的,您可以通过在一个 ALTER 中使用两个操作来做到这一点。

    ALTER TABLE my_table 
      ADD COLUMN description varchar(100) DEFAULT 'A1', 
      ALTER COLUMN description SET DEFAULT 'B2';
    

    我已经验证了 DROP DEFAULT 在添加列的命令中不起作用,这与 SET DEFAULT NULL 不同。我不认为它真的有理由不工作,只是碰巧以错误的顺序让它工作,没有人费心强迫它以正确的顺序做。 (也许是因为没有人测试过那个确切的东西,所以意识到它已经坏了)

    您总是可以在不同的 ALTER 命令中执行它们。如果您担心有人可能会“看到”处于中间状态的表,您可以在单个事务中完成这两项操作。然后锁不会在两者之间释放,所以没有人可以看到它。在一个命令中执行多个操作的真正优点是不需要多次重写表。但是在这里,它根本不需要重写。

    【讨论】:

    • 对我有用,有多个版本。你用的是什么版本?他们的表有什么奇怪的吗(外来的、临时的、分区的等)
    • 你可以在db-fiddle.com/f/2CFNtdkLbc324etcsSrNTq/0看到它工作
    • 我的错,它有效,我将删除我的 cmets
    • 我只是不明白为什么当我将行 ALTER COLUMN description SET DEFAULT 'B2'; 替换为行 ALTER COLUMN description DROP DEFAULT; 时它不起作用。要删除默认值,似乎只有ALTER COLUMN description SET DEFAULT NULL 可以工作。
    【解决方案2】:

    引用最近的docs,这个操作可以用两条语句来完成。

    1. 使用旧的默认值添加列

    ALTER TABLE my_table ADD COLUMN description varchar(100) DEFAULT 'A1';

    1. 修改列以使用不同的默认值

    ALTER TABLE my_table ALTER COLUMN description SET DEFAULT 'B2'

    下面包含了一个完整的可重现样本:

    CREATE TABLE my_table (
      "name" VARCHAR(5),
      "work" VARCHAR(9)
    );
    
    INSERT INTO my_table
      ("name", "work")
    VALUES
      ('bob', 'fireman'),
      ('carl', 'teacher'),
      ('alice', 'policeman');
    

    查询 #1

    select * from my_table;
    
    name work
    bob fireman
    carl teacher
    alice policeman

    查询 #2

    ALTER TABLE my_table 
    ADD COLUMN description varchar(100) 
    DEFAULT 'A1';
    

    没有要显示的结果。


    查询 #3

    select * from my_table;
    
    name work description
    bob fireman A1
    carl teacher A1
    alice policeman A1

    查询 #4

    ALTER TABLE my_table 
    ALTER COLUMN description SET DEFAULT 'B2';
    

    没有要显示的结果。


    查询 #5

    INSERT INTO my_table("name", "work")
    VALUES ('karen', 'developer');
    

    没有要显示的结果。


    查询 #6

    select * from my_table;
    
    name work description
    bob fireman A1
    carl teacher A1
    alice policeman A1
    karen developer B2

    View working demo on DB Fiddle

    让我知道这是否适合你。

    【讨论】:

    • 谢谢,我在问是否有办法运行“通过添加新列更新表并将其默认设置为 A1”和“通过将新列默认设置为 B2 来更新表”命令一次,只需一个查询。
    • @Tms91 你问了一个好问题。但是,我在最新的文档中没有看到这样的内容(在这篇文章的时候)。也许他们会在以后的版本中考虑这个,您可以提交请求hereengage them further
    猜你喜欢
    • 2010-09-10
    • 1970-01-01
    • 2021-01-17
    • 1970-01-01
    • 2016-09-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多