复合类型
复合类型表示行或记录的结构,它本质上就是字段名及其数据类型的列表。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 ... |
如果没有额外的圆括号,这将生成一个语法错误。