ALTER TYPE — 更改一个类型的定义
ALTER TYPEnameOWNER TO {new_owner| CURRENT_ROLE | CURRENT_USER | SESSION_USER } ALTER TYPEnameRENAME TOnew_nameALTER TYPEnameSET SCHEMAnew_schemaALTER TYPEnameRENAME ATTRIBUTEattribute_nameTOnew_attribute_name[ CASCADE | RESTRICT ] ALTER TYPEnameaction[, ... ] ALTER TYPEnameADD VALUE [ IF NOT EXISTS ]new_enum_value[ { BEFORE | AFTER }neighbor_enum_value] ALTER TYPEnameRENAME VALUEexisting_enum_valueTOnew_enum_valueALTER TYPEnameSET (property=value[, ... ] ) whereactionis one of: ADD ATTRIBUTEattribute_namedata_type[ COLLATEcollation] [ CASCADE | RESTRICT ] DROP ATTRIBUTE [ IF EXISTS ]attribute_name[ CASCADE | RESTRICT ] ALTER ATTRIBUTEattribute_name[ SET DATA ] TYPEdata_type[ COLLATEcollation] [ CASCADE | RESTRICT ]
ALTER TYPE 更改一个现有类型的定义。它有若干子形式:
OWNER这种形式更改该类型的拥有者。
RENAME这种形式更改该类型的名称。
SET SCHEMA这种形式将该类型移动到另一个模式中。
RENAME ATTRIBUTE这种形式只适用于组合类型。它更改该类型某个单独属性的名称。
ADD ATTRIBUTE 这种形式向组合类型添加一个新属性,使用的语法与 CREATE TYPE 相同。
DROP ATTRIBUTE [ IF EXISTS ] 这种形式从组合类型中删除一个属性。如果指定了 IF EXISTS 并且该属性不存在,则不会抛出错误。这种情况下会改为发出一个提示。
ALTER ATTRIBUTE ... SET DATA TYPE这种形式更改组合类型某个属性的类型。
ADD VALUE [ IF NOT EXISTS ] [ BEFORE | AFTER ] 这种形式向枚举类型添加一个新值。新值在枚举排序中的位置可以指定为位于某个现有值的 BEFORE 或 AFTER 位置。否则,新项会被添加到值列表的末尾。
如果指定了 IF NOT EXISTS,那么当该类型已经包含新值时并不是一个错误:会发出一个提示,但不采取其他任何行动。否则,如果新值已经存在,将会发生错误。
RENAME VALUE这种形式重命名枚举类型的一个值。该值在枚举排序中的位置不受影响。如果指定的值不存在或者新名称已经存在,将会发生错误。
SET ( property = value [, ... ] )
这种形式只适用于基础类型。它允许调整在 CREATE TYPE 中可以设置的基础类型属性的一个子集。具体来说,可以更改这些属性:
RECEIVE 可以被设置为一个二进制输入函数的名称,或者设置为 NONE 来移除该类型的二进制输入函数。使用这个选项需要超级用户特权。
SEND 可以被设置为一个二进制输出函数的名称,或者设置为 NONE 以移除该类型的二进制输出函数。使用此选项需要超级用户特权。
TYPMOD_IN 可以被设置为一个类型修改符输入函数的名称,或者设置为 NONE 以移除该类型的类型修改符输入函数。使用此选项需要超级用户特权。
TYPMOD_OUT 可以被设置为一个类型修改符输出函数的名称,或者设置为 NONE 以移除该类型的类型修改符输出函数。使用此选项需要超级用户特权。
ANALYZE 可以被设置为一个特定于类型的统计信息收集函数的名称,或者设置为 NONE 以移除该类型的统计信息收集函数。使用此选项需要超级用户特权。
SUBSCRIPT 可以被设置为一个特定于类型的下标处理函数的名称,或者设置为 NONE 以移除该类型的下标处理函数。使用此选项需要超级用户特权。
STORAGE 可以被设置为 plain、extended、external 或 main(有关这些值含义的更多信息请参见 Section 66.2)。但是,从 plain 更改为其他设置需要超级用户特权(因为它要求该类型的 C 函数全部是可 TOAST 的),而从其他设置更改为 plain 则完全不被允许(因为该类型在数据库中可能已经存在 TOAST 过的值)。注意,更改此选项本身并不会更改任何已存储的数据,它只是设置未来创建的表列将使用的默认 TOAST 策略。要更改现有表列的 TOAST 策略,请参见 ALTER TABLE。
关于这些类型属性的更多细节,请参阅 CREATE TYPE。注意,在适当的情况下,对基础类型这些属性的更改将自动传播到基于该类型的域上。
ADD ATTRIBUTE、DROP ATTRIBUTE 和 ALTER ATTRIBUTE 动作可以组合成一个包含多个更改的列表以并行应用。例如,可以在单个命令中添加多个属性和/或更改多个属性的类型。
你必须拥有该类型才能使用 ALTER TYPE。要更改类型的模式,你还必须在新模式上拥有 CREATE 特权。要更改拥有者,你必须能够 SET ROLE 到新的拥有角色,并且该角色必须在类型所在模式上拥有 CREATE 特权(这些限制强制确保更改拥有者不会做任何你通过删除并重建类型也无法完成的事情。不过,超级用户无论如何都能更改任何类型的拥有权)。要添加属性或更改属性类型,你还必须在属性的数据类型上拥有 USAGE 特权。
name要更改的现有类型的名称(可以用模式限定)。
new_name该类型的新名称。
new_owner该类型新拥有者的用户名。
new_schema该类型的新模式。
attribute_name要添加、更改或删除的属性的名称。
new_attribute_name要重命名的属性的新名称。
data_type要添加的属性的数据类型,或者要更改的属性的新类型。
new_enum_value要添加到枚举类型值列表中的新值,或者要赋予现有值的新名称。与所有枚举字面值一样,它需要加引号。
neighbor_enum_value在枚举类型的排序中,新值应该被紧邻添加在其之前或之后的现有枚举值。与所有枚举字面值一样,它需要加引号。
existing_enum_value应该被重命名的现有枚举值。与所有枚举字面值一样,它需要加引号。
property要修改的基类型属性的名称;可能的值见上文。
CASCADE自动将该操作传播到被更改类型的类型化表及其后代。
RESTRICT如果被更改的类型是某个类型化表的类型,则拒绝该操作。这是默认行为。
如果 ALTER TYPE ... ADD VALUE(向枚举类型添加新值的形式)在事务块内被执行,那么在事务提交之后才能使用该新值。
涉及新增枚举值的比较有时会比只涉及枚举类型原始成员的比较慢。这通常只会在使用 BEFORE 或 AFTER 将新值的排序位置设置在列表末尾以外的某处时发生。不过,有时即使新值被添加在末尾也会发生这种情况(如果自枚举类型最初创建以来 OID 计数器发生了“回绕”,就会出现这种情况)。这种变慢通常无关紧要;但如果它确实有影响,可以通过删除并重建该枚举类型,或者通过转储并恢复数据库来重新获得最佳性能。
重命名一个数据类型:
ALTER TYPE electronic_mail RENAME TO email;
将类型 email 的拥有者更改为 joe:
ALTER TYPE email OWNER TO joe;
将类型 email 的模式更改为 customers:
ALTER TYPE email SET SCHEMA customers;
向组合类型添加一个新属性:
ALTER TYPE compfoo ADD ATTRIBUTE f3 int;
向枚举类型在特定排序位置添加一个新值:
ALTER TYPE colors ADD VALUE 'orange' AFTER 'red';
重命名一个枚举值:
ALTER TYPE colors RENAME VALUE 'purple' TO 'mauve';
为一个现有基类型创建二进制 I/O 函数:
CREATE FUNCTION mytypesend(mytype) RETURNS bytea ...;
CREATE FUNCTION mytyperecv(internal, oid, integer) RETURNS mytype ...;
ALTER TYPE mytype SET (
SEND = mytypesend,
RECEIVE = mytyperecv
);
添加和删除属性的变体是 SQL 标准的一部分;其他变体是 PostgreSQL 的扩展。