跳到主要内容

ALTER TABLE 语句

ALTER TABLE 语句用于更改目录中现有表的 schema。

示例

CREATE TABLE integers (i INTEGER, j INTEGER);

向表 integers 添加一个名为 k 的新列;该列会以默认值 NULL 填充:

ALTER TABLE integers
ADD COLUMN k INTEGER;

向表 integers 添加一个名为 l 的新列;该列会以默认值 10 填充:

ALTER TABLE integers
ADD COLUMN l INTEGER DEFAULT 10;

从表 integers 中删除列 k

ALTER TABLE integers
DROP k;

使用标准类型转换将列 i 的类型改为 VARCHAR

ALTER TABLE integers
ALTER i TYPE VARCHAR;

将列 i 的类型改为 VARCHAR,并使用指定表达式转换每一行的数据:

ALTER TABLE integers
ALTER i SET DATA TYPE VARCHAR USING concat(i, '_', j);

设置列的默认值:

ALTER TABLE integers
ALTER COLUMN i SET DEFAULT 10;

删除列的默认值:

ALTER TABLE integers
ALTER COLUMN i DROP DEFAULT;

将列设为不可为 NULL

ALTER TABLE integers
ALTER COLUMN i SET NOT NULL;

移除非 NULL 约束:

ALTER TABLE integers
ALTER COLUMN i DROP NOT NULL;

重命名表:

ALTER TABLE integers
RENAME TO integers_old;

重命名表中的列:

ALTER TABLE integers
RENAME i TO ii;

为表中的列添加主键:

ALTER TABLE integers
ADD PRIMARY KEY (i);

语法

ALTER TABLE 会更改现有表的 schema。
ALTER TABLE 所做的所有更改都完全遵循事务语义,即在提交之前对其他事务不可见,并且可以通过回滚完全撤销。

RENAME TABLE

重命名表:

ALTER TABLE integers
RENAME TO integers_old;

RENAME TO 子句用于重命名整张表,即更改其在 schema 中的名称。请注意,任何依赖该表的视图都不会自动更新。

RENAME COLUMN

要重命名表中的列,请使用 RENAMERENAME COLUMN 子句:

ALTER TABLE integers 
RENAME COLUMN i TO j;
ALTER TABLE integers
RENAME i TO j;

RENAME [COLUMN] 子句用于重命名表中的单个列。任何依赖该名称的约束(例如 CHECK 约束)会自动更新。
但请注意,任何依赖该列名的视图都不会自动更新。

ADD COLUMN

要为表添加列,请使用 ADDADD COLUMN 子句。

例如,向表 integers 添加名为 k 的新列;该列会以默认值 NULL 填充:

ALTER TABLE integers
ADD COLUMN k INTEGER;

或者:

ALTER TABLE integers
ADD k INTEGER;

向表 integers 添加一个名为 l 的新列;该列会以默认值 10 填充:

ALTER TABLE integers
ADD COLUMN l INTEGER DEFAULT 10;

ADD [COLUMN] 子句可用于向表添加指定类型的新列。新列会以指定默认值填充;如果未指定,则使用 NULL

DROP COLUMN

要删除表中的列,请使用 DROPDROP COLUMN 子句:

例如,从表 integers 中删除列 k

ALTER TABLE integers
DROP COLUMN k;

或者:

ALTER TABLE integers
DROP k;

DROP [COLUMN] 子句可用于从表中移除列。请注意,仅当没有索引依赖该列时,才能删除该列。
这包括作为 PRIMARY KEYUNIQUE 约束一部分创建的任何索引。属于多列 CHECK 约束的列也不能被删除。
如果你尝试删除存在索引的列,Goose 会返回以下错误信息:

Dependency Error:
Cannot alter entry "..." because there are entries that depend on it.

[SET [DATA]] TYPE

使用标准类型转换将列 i 的类型改为 VARCHAR

ALTER TABLE integers
ALTER i TYPE VARCHAR;

除了 ALTER ⟨column_name⟩ TYPE ⟨type⟩,你也可以使用等价的 ALTER ⟨column_name⟩ SET TYPE ⟨type⟩ 以及 ALTER ⟨column_name⟩ SET DATA TYPE ⟨type⟩ 子句。

将列 i 的类型改为 VARCHAR,并使用指定表达式转换每一行的数据:

ALTER TABLE integers
ALTER i SET DATA TYPE VARCHAR USING concat(i, '_', j);

[SET [DATA]] TYPE 子句用于更改表中某列的类型。列中已有数据会根据 USING 子句提供的表达式进行转换;如果没有 USING 子句,则会转换为新数据类型。
请注意,仅当没有索引依赖该列且该列不属于任何 CHECK 约束时,才能修改其类型。

处理 Struct

有两种方式可以更改 STRUCT 类型列的子 schema。

使用 struct_insertALTER TABLE

你可以将 ALTER TABLEstruct_insert 函数结合使用。
例如:

CREATE TABLE tbl (col STRUCT(i INTEGER));
ALTER TABLE tbl
ALTER col TYPE USING struct_insert(col, a := 42, b := NULL::VARCHAR);

使用 ADD COLUMN / DROP COLUMN / RENAME COLUMNALTER TABLE

从 Goose v1.3.0 开始,ALTER TABLE 支持 ADD COLUMNDROP COLUMNRENAME COLUMN 子句 以更新 STRUCT 的子 schema。

SET / DROP DEFAULT

设置列的默认值:

ALTER TABLE integers
ALTER COLUMN i SET DEFAULT 10;

删除列的默认值:

ALTER TABLE integers
ALTER COLUMN i DROP DEFAULT;

SET/DROP DEFAULT 子句会修改现有列的 DEFAULT 值。请注意,这不会修改该列中已有的数据。删除默认值等同于将默认值设为 NULL。

警告:目前如果存在任何依赖,Goose 不允许你修改表。也就是说,如果某列上有索引,你需要先删除索引,修改表,然后重新创建索引。否则会得到 Dependency Error

ADD PRIMARY KEY

为表中的列添加主键:

ALTER TABLE integers
ADD PRIMARY KEY (i);

为表中的多列添加主键:

ALTER TABLE integers
ADD PRIMARY KEY (i, j);

ADD / DROP CONSTRAINT

Goose 目前尚不支持 ADD CONSTRAINTDROP CONSTRAINT 子句。

限制

如果表中在任何时刻出现过冲突类型的值,ALTER COLUMN 就会失败,即使这些值后来已被删除:

CREATE TABLE tbl (col VARCHAR);

INSERT INTO tbl
VALUES ('asdf'), ('42');

DELETE FROM tbl
WHERE col = 'asdf';

ALTER TABLE tbl
ALTER COLUMN col TYPE INTEGER;
Conversion Error:
Could not convert string 'asdf' to INT32

当前这是预期行为。
作为一种变通方案,你可以创建该表的副本:

CREATE OR REPLACE TABLE tbl AS FROM tbl;