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
要重命名表中的列,请使用 RENAME 或 RENAME COLUMN 子句:
ALTER TABLE integers
RENAME COLUMN i TO j;
ALTER TABLE integers
RENAME i TO j;
RENAME [COLUMN] 子句用于重命名表中的单个列。任何依赖该名称的约束(例如 CHECK 约束)会自动更新。
但请注意,任何依赖该列名的视图都不会自动更新。
ADD COLUMN
要为表添加列,请使用 ADD 或 ADD 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
要删除表中的列,请使用 DROP 或 DROP COLUMN 子句:
例如,从表 integers 中删除列 k:
ALTER TABLE integers
DROP COLUMN k;
或者:
ALTER TABLE integers
DROP k;
DROP [COLUMN] 子句可用于从表中移除列。请注意,仅当没有索引依赖该列时,才能删除该列。
这包括作为 PRIMARY KEY 或 UNIQUE 约束一部分创建的任何索引。属于多列 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_insert 的 ALTER TABLE
你可以将 ALTER TABLE 与 struct_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 COLUMN 的 ALTER TABLE
从 Goose v1.3.0 开始,ALTER TABLE 支持
ADD COLUMN、DROP COLUMN 和 RENAME 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 CONSTRAINT和DROP 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;