CREATE DOMAIN
CREATE DOMAIN - 定义一个新域
语法格式
CREATE DOMAIN name [ AS ] data_type
[ COLLATE collation ]
[ DEFAULT expression ]
[ constraint [ ... ] ]
其中 constraint 是:
[ CONSTRAINT constraint_name ]
{ NOT NULL | NULL | CHECK (expression) }
说明
CREATE DOMAIN创建一个新域。域本质上是具有可选约束的数据类型(对允许的值集的限制)。定义域的用户将成为其所有者。
如果给出了模式名称(例如, CREATE DOMAIN myschema.mydomain …),则会在指定的模式中创建域。否则,它将在当前架构中创建。域名在其架构中存在的类型和域中必须是唯一的。
域可用于将字段上的常见约束抽象到单个位置以进行维护。例如,几个表可能包含电子邮件地址列,所有这些列都需要相同的CHECK约束来验证地址语法。定义域而不是单独设置每个表的约束。
要能够创建域,您必须具有基础类型的 USAGE 权限。
参数说明
name
要被创建的域的名称(可以被模式限定)。
data_type
域的底层数据类型。可以包括数组指示符。
collation
用于该域的可选的排序规则。如果没有指定排序规则,将使用底层 数据类型的默认排序规则。如果指定了COLLATE, 底层类型必须是可排序的。
DEFAULT expression
DEFAULT子句为该域数据类型的列指定一个默认值。 该值是任何没有变量的表达式(但不允许子查询)。默认值表达式 的数据类型必须匹配域的数据类型。如果没有指定默认值,那么 默认值就是空值。 默认值表达式将被用在任何没有指定列值的插入操作中。如果为一个 特定列定义了默认值,它会覆盖与域相关的默认值。继而,域默认值 会覆盖任何与底层数据类型相关的默认值。
CONSTRAINT constraint_name
一个约束的名称(可选)。如果没有指定,系统会生成一个名称。
NOT NULL
这个域的值通常不能为空值(但是看看下面的注释)。
NULL
这个域的值允许为空值。这是默认值。 这个子句只是为了与非标准 SQL 数据库相兼容而设计。在新的 应用中不鼓励使用它。
CHECK (expression)
CHECK子句指定该域的值必须满足的完整性 约束或者测试。每一个约束必须是一个产生布尔结果的表达式。 它应该使用关键词VALUE来引用要被测试的值。计算为 TRUE 或者 UNKNOWN 的表达式成功。如果该表达式产生一个 FALSE 结果,会报告一个错误并且该值不允许被转换成该域类型。 当前,CHECK表达式不能包含子查询,也不能 引用除VALUE之外的其他变量。 当一个域有多个CHECK约束,将按照其名字的 字母顺序测试它们(版本 9.5 之前的Vastbase E100 不遵循任何用于CHECK约束的特定触发顺序)。
注意事项
将值转换为域类型时,将检查域约束,尤其是 NOT NULL 。尽管存在这样的约束,但名义上为域类型的列可能读为空。例如,如果域列位于外部联接的可空区域,则可能会发生在外部联接查询中。一个更微妙的示例是
INSERT INTO tab (domcol) VALUES ((SELECT domcol FROM tab WHERE false));
空标量子SELECT将生成一个被认为属于域类型的空值,因此不会对其应用进一步的约束检查,并且插入将成功。
由于SQL的一般假设是空值是每种数据类型的有效值,因此很难避免此类问题。因此,最佳做法是设计域的约束以允许空值,然后根据需要将列NOT NULL 约束应用于域类型的列,而不是直接应用于域类型。
示例
此示例创建 us_postal_code数据类型,然后在表定义中使用该类型。正则表达式测试用于验证该值看起来像有效的美国邮政编码:
CREATE DOMAIN us_postal_code AS TEXT
CHECK(
VALUE ~ '^\d{5}$'
OR VALUE ~ '^\d{5}-\d{4}$'
);
CREATE TABLE us_snail_addy (
address_id SERIAL PRIMARY KEY,
street1 TEXT NOT NULL,
street2 TEXT,
street3 TEXT,
city TEXT NOT NULL,
postal us_postal_code NOT NULL
);