更新时间:2024-09-02 GMT+08:00

复合类型

复合类型表示行或记录的结构,它本质上就是字段名及其数据类型的列表。GaussDB(DWS)允许支持将表的列声明为复合类型。复合类型本质上和表的行类型相同,但是如果只想定义一种类型,使用CREATE TYPE可避免创建一个实际的表。单独的复合类型也是很有用的,例如可以作为函数的参数或者返回类型。

复合类型的声明

GaussDB(DWS)支持用户使用CREATE TYPE定义复合类型:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
CREATE TYPE complex AS (
        r       double precision,
        i       double precision
    );

CREATE TYPE inventory_item AS (
        name            text,
        supplier_id     integer,
        price           numeric
    );

定义复合类型之后,可用来创建表或函数:

1
2
3
4
5
6
CREATE TABLE on_hand (
        item      inventory_item,
        count     integer
    );

INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);
1
2
3
4
CREATE FUNCTION price_extension(inventory_item, integer) RETURNS numeric
    AS 'SELECT $1.price * $2' LANGUAGE SQL;

SELECT price_extension(item, 10) FROM on_hand;

构造复合值

要把复合值写作文字常量,可以将字段值括在圆括号中,并用逗号分隔。可以在任何字段值加上双引号,如果字段值包含逗号或括号则必须这样做。复合常量的一般格式如下:

1
'( val1 , val2 , ... )'

上文中的'("fuzzy dice",42,1.99)'便属于inventory_item类型的一个合法值。

要让一个字段为NULL,在列表中对应位置上空出即可。如果需要一个字段为空字符串,使用引号即可。例如下列示例,第一个字段是非NULL空字符串,第三个是NULL:

1
'("",42,)'

ROW表达式也能被用来构建组合值。例如:

1
2
ROW('fuzzy dice', 42, 1.99)
ROW('', 42, NULL)

访问组合类型

要访问复合列的字段,可以写成一个点和字段的名称,就像从表名中选择字段一样。为了避免混淆,必须使用括号进行区分。例如,尝试从示例表on_hand中选择一些子域:

1
2
SELECT item.name FROM on_hand WHERE item.price > 9.99;
ERROR:  missing FROM-clause entry for table "item"

这样写是会与从表中选择字段混淆的,因为名称item会被当成是一个表名,而不是on_hand的一个列名。必须写成这样:

1
SELECT (item).name FROM on_hand WHERE (item).price > 9.99;

或者还需要使用表名(例如在一个多表查询中):

1
SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;

现在加上括号的对象就被正确地解释为对item列的引用,然后可以从中选出子域。

只要从一个组合值中选择一个字段,相似的语法问题就适用。例如,要从返回组合值的函数的结果中选取一个字段,需要这样写:

1
SELECT (my_func(...)).field FROM ...

如果没有额外的圆括号,这将生成一个语法错误。