ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
action [, ... ]
ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
RENAME [ COLUMN ] column_name TO new_column_name
ALTER TABLE [ IF EXISTS ] [ ONLY ] name [ * ]
RENAME CONSTRAINT constraint_name TO new_constraint_name
ALTER TABLE [ IF EXISTS ] name
RENAME TO new_name
ALTER TABLE [ IF EXISTS ] name
SET SCHEMA new_schema
ALTER TABLE ALL IN TABLESPACE name [ OWNED BY role_name [, ... ] ]
SET TABLESPACE new_tablespace [ NOWAIT ]
ALTER TABLE [ IF EXISTS ] name
ATTACH PARTITION partition_name { FOR VALUES partition_bound_spec | DEFAULT }
ALTER TABLE [ IF EXISTS ] name
DETACH PARTITION partition_name
where action is one of:
ADD [ COLUMN ] [ IF NOT EXISTS ] column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
DROP [ COLUMN ] [ IF EXISTS ] column_name [ RESTRICT | CASCADE ]
ALTER [ COLUMN ] column_name [ SET DATA ] TYPE data_type [ COLLATE collation ] [ USING expression ]
ALTER [ COLUMN ] column_name SET DEFAULT expression
ALTER [ COLUMN ] column_name DROP DEFAULT
ALTER [ COLUMN ] column_name { SET | DROP } NOT NULL
ALTER [ COLUMN ] column_name DROP EXPRESSION [ IF EXISTS ]
ALTER [ COLUMN ] column_name ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ]
ALTER [ COLUMN ] column_name { SET GENERATED { ALWAYS | BY DEFAULT } | SET sequence_option | RESTART [ [ WITH ] restart ] } [...]
ALTER [ COLUMN ] column_name DROP IDENTITY [ IF EXISTS ]
ALTER [ COLUMN ] column_name SET STATISTICS integer
ALTER [ COLUMN ] column_name SET ( attribute_option = value [, ... ] )
ALTER [ COLUMN ] column_name RESET ( attribute_option [, ... ] )
ALTER [ COLUMN ] column_name SET STORAGE { PLAIN | EXTERNAL | EXTENDED | MAIN }
ADD table_constraint [ NOT VALID ]
ADD table_constraint_using_index
ALTER CONSTRAINT constraint_name [ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
VALIDATE CONSTRAINT constraint_name
DROP CONSTRAINT [ IF EXISTS ] constraint_name [ RESTRICT | CASCADE ]
DISABLE TRIGGER [ trigger_name | ALL | USER ]
ENABLE TRIGGER [ trigger_name | ALL | USER ]
ENABLE REPLICA TRIGGER trigger_name
ENABLE ALWAYS TRIGGER trigger_name
DISABLE RULE rewrite_rule_name
ENABLE RULE rewrite_rule_name
ENABLE REPLICA RULE rewrite_rule_name
ENABLE ALWAYS RULE rewrite_rule_name
DISABLE ROW LEVEL SECURITY
ENABLE ROW LEVEL SECURITY
FORCE ROW LEVEL SECURITY
NO FORCE ROW LEVEL SECURITY
CLUSTER ON index_name
SET WITHOUT CLUSTER
SET WITHOUT OIDS
SET TABLESPACE new_tablespace
SET { LOGGED | UNLOGGED }
SET ( storage_parameter [= value] [, ... ] )
RESET ( storage_parameter [, ... ] )
INHERIT parent_table
NO INHERIT parent_table
OF type_name
NOT OF
OWNER TO { new_owner | CURRENT_USER | SESSION_USER }
REPLICA IDENTITY { DEFAULT | USING INDEX index_name | FULL | NOTHING }
and partition_bound_spec is:
IN ( partition_bound_expr [, ...] ) |
FROM ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] )
TO ( { partition_bound_expr | MINVALUE | MAXVALUE } [, ...] ) |
WITH ( MODULUS numeric_literal, REMAINDER numeric_literal )
and column_constraint is:
[ CONSTRAINT constraint_name ]
{ NOT NULL |
NULL |
CHECK ( expression ) [ NO INHERIT ] |
DEFAULT default_expr |
GENERATED ALWAYS AS ( generation_expr ) STORED |
GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( sequence_options ) ] |
UNIQUE index_parameters |
PRIMARY KEY index_parameters |
REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
[ ON DELETE referential_action ] [ ON UPDATE referential_action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
and table_constraint is:
[ CONSTRAINT constraint_name ]
{ CHECK ( expression ) [ NO INHERIT ] |
UNIQUE ( column_name [, ... ] ) index_parameters |
PRIMARY KEY ( column_name [, ... ] ) index_parameters |
EXCLUDE [ USING index_method ] ( exclude_element WITH operator [, ... ] ) index_parameters [ WHERE ( predicate ) ] |
FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
[ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE referential_action ] [ ON UPDATE referential_action ] }
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
and table_constraint_using_index is:
[ CONSTRAINT constraint_name ]
{ UNIQUE | PRIMARY KEY } USING INDEX index_name
[ DEFERRABLE | NOT DEFERRABLE ] [ INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
index_parameters in UNIQUE, PRIMARY KEY, and EXCLUDE constraints are:
[ INCLUDE ( column_name [, ... ] ) ]
[ WITH ( storage_parameter [= value] [, ... ] ) ]
[ USING INDEX TABLESPACE tablespace_name ]
exclude_element in an EXCLUDE constraint is:
{ column_name | ( expression ) } [ opclass ] [ ASC | DESC ] [ NULLS { FIRST | LAST } ]
說明
ALTER TABLE 變更現有資料表的定義。有幾個子命令描述如下。請注意,每個子命令所需的鎖定等級可能不同。除非明確指出,否則都是 ACCESS EXCLUSIVE 鎖定。當列出多個子命令時,所有子命令所需的鎖以最嚴格的為準。
ADD COLUMN [ IF NOT EXISTS ]
該資料表使用與 CREATE TABLE 相同的語法在資料表中增加一個新的欄位。如果 IF NOT EXISTS 被指定,並且欄位已經存在這個名稱,則可以避免引發錯誤。
DROP COLUMN [ IF EXISTS ]
從該資料表中刪除一個欄位。涉及該欄位的索引和資料表限制條件也將自動刪除。如果刪除的欄位會導致統計信息僅包含單個欄位的資料的話,那麼引用刪除欄位的多變量統計數據也將被刪除。如果資料表外的任何內容取決於該欄位,例如外部鍵引用或 view,則需要使用 CASCADE。 如果指定 IF EXISTS 但該欄位卻不存在,則不會引發錯誤。通常在這種情況下,會發出提示訊息。
SET DATA TYPE
這種語法用於變更一個資料表中欄位的資料型別。涉及該欄位的索引和簡單的資料表限制條件將透過重新分析原始提供的表示式自動轉換為使用新的欄位型別。可選用的 COLLATE 子句指定新欄位的排序規則;如果省略的話,則排序規則是新欄位型別的預設值。可選用的 USING 子句指定如何從舊值計算為新的欄位值;如果省略,則預設轉換與從舊資料類型到新欄位轉換的賦值相同。 如果沒有隱含或賦值從舊型別轉換為新型別,則必須提供 USING 子句。
這個語法會變更欄位是否標記為允許空值或拒絕空值。當欄位不應該包含空值時,您就可以使用 SET NOT NULL。
如果此資料表是一個資料表分割區,而在父資料表中標記為 NOT NULL,則不能在欄位上執行 DROP NOT NULL。要從所有分割區中刪除 NOT NULL 約束,請在父資料表上執行 DROP NOT NULL。即使父級沒有 NOT NULL 限制條件,如果需要,這樣的限制條件仍然可以加到單獨的分割區中;也就是說,即使父資料表允許他們,子資料表們也可以不允許使用空值,但是反過來也是如此。
ADD GENERATED { ALWAYS | BY DEFAULT } AS IDENTITYSET GENERATED { ALWAYS | BY DEFAULT }DROP IDENTITY [ IF EXISTS ]
此語法在資料表中增加了一個 oid 系統欄位(參閱第 5.4 節)。 如果資料表已經有 OID,那就什麼都不做。
請注意,這不等同於 ADD COLUMN oid oid;那只會增加一個正常的欄位,而它碰巧被命名為 oid,而不是系統欄位。
SET WITHOUT OIDS
此語法從資料表中移除 oid 系統欄位。這完全等同於 DROP COLUMN oid RESTRICT,只是如果已經沒有 oid 欄位,它不會有動作產生。
SET TABLESPACE
此語法將資料表的資料表空間更改為指定的資料表空間,並將與資料表關聯的資料檔案移動到新的資料表空間。資料表中的索引(如果有的話)不會移動;但它們可以通過額外的 SET TABLESPACE 指令單獨移動。資料表空間中目前資料庫中的所有資料表都可以通過使用 ALL IN TABLESPACE 語法來移動,它將鎖定所有要移動的資料表,然後移動每個資料表。這種語法也支持 OWNED BY,它只會移動指定角色擁有的資料表。 如果指定了 NOWAIT 選項,那麼如果無法立即取得所有需要的鎖定,該指令將失敗。請注意,如果需要,系統目錄不會被此指令移動,而是使用 ALTER DATABASE 或 ALTER TABLE 呼叫。information_schema 關連不被視為系統目錄的一部分,將會被移動。另請參閱 CREATE TABLESPACE。
雖然 CREATE TABLE 允許在 WITH(storage_parameter)語法中指定 OIDS,但 ALTER TABLE 不會將 OIDS 視為儲存參數。而是使用 SET WITH OIDS 和 SET WITHOUT OIDS 語法來變更 OID 狀態。
RESET (storage_parameter [, ... ] )
此語法將一個或多個儲存參數重置為其預設值。 和 SET 一樣,可能需要重新寫入資料來完成更新其效果。
INHERITparent_table
此子句將目標資料表加到指定的父資料表中成為新的子資料表。然後,針對父資料表的查詢將會包含目標資料表的資料。要作為子資料表加入前,目標資料表必須已經包含與父資料表的所有欄位(它也可以具有其他欄位)。這些欄位必須具有可匹配的資料型別,並且如果它們在父資料表中具有 NOT NULL 限制條件,那麼它們還必須在子資料表中也具有 NOT NULL 限制條件。
此子句將資料表連接到複合型別,就像 CREATE TABLE OF 已經産生它一樣。該資料表的欄位名稱和型別必須與組合型別的列表完全吻合;oid 系統欄位的存在會有所不同。該資料表不得從任何其他的資料表繼承。這些限制確保了 CREATE TABLE OF 將得到一個等效的資料表定義。
NOT OF
此子句將複合型別資料表從它的型別中分離出來。
OWNER
該子句將資料表、序列、檢視表、具體化檢視表或外部資料表的擁有者變更為指定的使用者。
REPLICA IDENTITY
此子句變更寫入 WAL 的訊息,以識別更新或刪除的資料列。如果正在使用邏輯複製的話,則此子句不起作用。DEFAULT(非系統資料表的預設值)記錄主鍵欄位的舊值(如果有的話)。USING INDEX 記錄指定索引覆蓋欄位的舊值,它必須是唯一的,不能是部分的,也不可是延遲的,並且只能包含標記為 NOT NULL 的欄位。FULL 記錄行中所有欄位的舊值。 沒有記錄關於舊資料列的訊息。(這是系統資料表的預設值。)在任何情況下,都不記錄舊值,除非至少有一個將記錄的欄位在新舊版本的資料列之間不同。
使用 DEFAULT 子句增加欄位或變更現有欄位的型別會需要重寫整個資料表及其索引。變更現有欄位型別時的例外情況,如果 USING 子句不變更欄位內容,並且舊型別可以是新型別的二進制強製或新類型的不受限制的 domain,則不需要重寫資料表;但受影響欄位上的任何索引仍必須重建。增加或刪除系統 oid 欄位也需要重寫整個資料表。資料表和索引重建對於大型資料表來說,可能需要大量時間,並且暫時需要可能多達兩倍的磁碟空間。
增加 CHECK 或 NOT NULL 限制條件需要掃描資料表以驗證現有的資料列是否滿足限制條件,但不需要重寫資料表。
同樣,在附加新分割區時,可能會掃描它們以驗證現有資料是否符合分割區的限制條件。
提供在單個 ALTER TABLE 中指定多個變更選項的主要原因是多個資料表掃描或重寫可以因此在資料表中組合成單次作業。
DROP COLUMN 資料表不會在實體上刪除欄位,而只是使其對 SQL 操作設為不可見。資料表中的後續插入和更新操作將該欄位儲存為空值。因此,刪除欄位很快,但不會立即減少資料表的磁碟大小,因為所刪除的欄位所佔用的空間並不會被回收。隨著現有資料的更新,空間將隨著時間的推移而被回收。(這些語句在刪除系統 oid 欄位時不適用,這是透過立即重寫完成的。)
要強制立即回收被刪除的欄位所佔用的空間,可以執行 ALTER TABLE 的一種語法來執行整個資料表的重寫。這會導致重建每個資料列,並將刪除的欄位替換為空值。
ALTER TABLE 的重寫語法並不是 MVCC 安全的。在資料表重寫後,如果使用在重寫發生之前的快照,該資料表對於平行事務將會顯示為空。更多細節參閱 13.5 節。
SET DATA TYPE 的 USING 選項實際上可以指定涉及資料列舊值的任何表示式;也就是說,它可以引用其他欄位以及正在轉換的欄位。這允許使用 SET DATA TYPE 語法完成非常普遍的轉換。由於這種靈活性,USING 表示式並不適用於欄位的預設值(如果有的話); 結果可能不是預設所需的常數表示式。這意味著,如果沒有隱含或賦值從舊型別轉換為新型別,即使提供了 USING 子句,SET DATA TYPE 也可能無法轉換預設值。在這種情況下,請使用 DROP DEFAULT 刪除預設值,執行 ALTER TYPE,然後使用 SET DEFAULT 加上合適的新預設值。類似的考量適用於涉及該欄位的索引和限制條件。
如果資料表有任何後代資料表,則不允許在父資料表中增加、重新命名或變更欄位的型別,卻不對後代資料進行相同操作。這確保了後代資料總是有與父代資料匹配的欄位。同樣,如果不在所有後代資料表中重新命名限制條件,則不能在父級資料表中重新命名該限制條件,以便限制條件在父代資料及其後代資料表之間也匹配。此外,因為從父代資料中查詢也會從其後代資料中進行查詢,所以對父代資料表的限制條件不能被標記為有效,除非它對於那些後代資料表也被標記為有效。在所有這些情況下,ALTER TABLE ONLY 將會被拒絕。
遞迴的 DROP COLUMN 操作只有在後代資料表不從其他父代繼承該欄位並且從未擁有該欄位的獨立定義的情況下才會刪除後代資料表欄位。非遞迴 DROP COLUMN(即,ALTER TABLE ONLY ... DROP COLUMN)永遠不會刪除任何後代欄位,而是將它們標記為獨立定義而非繼承。對於分割區資料表,非遞迴 DROP COLUMN 命令將會失敗,因為資料表的所有分割區必須與分割區源頭具有相同的欄位。
ALTER TABLE distributors ADD COLUMN address varchar(30);
ALTER TABLE distributors DROP COLUMN address RESTRICT;
ALTER TABLE distributors
ALTER COLUMN address TYPE varchar(80),
ALTER COLUMN name TYPE varchar(100);
ALTER TABLE foo
ALTER COLUMN foo_timestamp SET DATA TYPE timestamp with time zone
USING
timestamp with time zone 'epoch' + foo_timestamp * interval '1 second';
ALTER TABLE foo
ALTER COLUMN foo_timestamp DROP DEFAULT,
ALTER COLUMN foo_timestamp TYPE timestamp with time zone
USING
timestamp with time zone 'epoch' + foo_timestamp * interval '1 second',
ALTER COLUMN foo_timestamp SET DEFAULT now();
ALTER TABLE distributors RENAME COLUMN address TO city;
ALTER TABLE distributors RENAME TO suppliers;
ALTER TABLE distributors RENAME CONSTRAINT zipchk TO zip_check;
ALTER TABLE distributors ALTER COLUMN street SET NOT NULL;
ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;
ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5) NO INHERIT;
ALTER TABLE distributors DROP CONSTRAINT zipchk;
ALTER TABLE ONLY distributors DROP CONSTRAINT zipchk;
ALTER TABLE distributors ADD CONSTRAINT distfk FOREIGN KEY (address) REFERENCES addresses (address) NOT VALID;
ALTER TABLE distributors VALIDATE CONSTRAINT distfk;
ALTER TABLE distributors ADD CONSTRAINT dist_id_zipcode_key UNIQUE (dist_id, zipcode);
ALTER TABLE distributors ADD PRIMARY KEY (dist_id);
ALTER TABLE distributors SET TABLESPACE fasttablespace;
ALTER TABLE myschema.distributors SET SCHEMA yourschema;
CREATE UNIQUE INDEX CONCURRENTLY dist_id_temp_idx ON distributors (dist_id);
ALTER TABLE distributors DROP CONSTRAINT distributors_pkey,
ADD CONSTRAINT distributors_pkey PRIMARY KEY USING INDEX dist_id_temp_idx;
ALTER TABLE measurement
ATTACH PARTITION measurement_y2016m07 FOR VALUES FROM ('2016-07-01') TO ('2016-08-01');
ALTER TABLE cities
ATTACH PARTITION cities_ab FOR VALUES IN ('a', 'b');
ALTER TABLE measurement
DETACH PARTITION measurement_y2015m12;