PostgreSQL 8.1 中文文档 | ||||
---|---|---|---|---|
Prev | Fast Backward | Chapter 8. 数据类型 | Fast Forward | Next |
Postgresql允许记录的字段定义成定长或不定长的多维数组。 数组类型可以是任何基本类型或用户定义类型。(不过,复合类型和域的数组还不支持。)
@H_404_30@8.10.1. 数组类型的声明
为说明这些用法,我们先创建一个由基本类型数组构成的表:
CREATE TABLE sal_emp ( name text,pay_by_quarter integer[],schedule text[][] );
如上所示,一个数组类型是通过在数组元素类型名后面附加方括弧([])来命名的。 上面的命令将创建一个叫sal_emp的表,它的字段中有一个text类型字符串(name), 一个一维integer型数组(pay_by_quarter), 代表雇员的季度薪水和一个两维text类型数组(schedule), 表示雇员的周计划。
CREATE TABLE的语法允许声明数组的确切大小,比如:
CREATE TABLE tictactoe ( squares integer[3][3] );
不过,目前的实现并不强制数组尺寸限制 — 其行为和用于未声明长度的 数组相同。
实际上,目前的声明也不强制数组维数。特定元素类型的数组都被认为是相同的类型, 不管他们的大小或者维数。因此,在CREATE TABLE里定义数字或者维数都只是简单的文档,它并不影响运行时的行为。
另外还有一种语法,它遵循 sql 标准,可以用于声明一维数组。pay_by_quarter可以定义为:
pay_by_quarter integer ARRAY[4],
这个语法要求一个整数常量表示数组尺寸。不过,和以前一样,Postgresql并不强制这个尺寸限制。
8.10.2. 数组值输入
把一个数组数值写成一个文本值的时候, 我们用花括弧把数值括起来并且用逗号将它们分开。 (如果你懂 C,那么这与初始化一个结构很像。) 你可以在任何数组值周围放置双引号,如果这个值包含逗号或者花括弧, 那么你就必须加上双引号。(下面有更多细节。)因此,一个数组常量的常见格式如下:
'{ val1 delim val2 delim ... }'
这里的delim是该类型的分隔符, 就是那个在它的pg_type记录里指定的那个。 在Postgresql发布提供的标准数据类型里, 类型Box使用分号(;),但是所有其它类型都用逗号(,)。 每个val要么是一个数组元素类型的常量,要么是一个子数组。一个数组常量的例子是
'{{1,2,3},{4,5,6},{7,8,9}}'
这个常量是一个两维的,3乘3的数组,由三个整数子数组组成。
(这种数组常量实际上只是我们在Section 4.1.2.5里讨论过的一般类型常量的一种特例。常量最初是当作字串看待并且传递给数组输入转换过程。可能需要我们用明确的类型声明。)
现在我们可以显示一些INSERT语句。
INSERT INTO sal_emp VALUES ('Bill','{10000,10000,10000}','{{"meeting","lunch"},{"meeting"}}'); ERROR: multidimensional arrays must have array expressions with matching dimensions
请注意多维数组必须匹配每个维的元素数。如果不匹配则导致错误发生。
INSERT INTO sal_emp VALUES ('Bill',{"training","presentation"}}'); INSERT INTO sal_emp VALUES ('Carol','{20000,25000,25000}','{{"breakfast","consulting"},{"meeting","lunch"}}');
目前的数组实现的一个局限是一个数组的独立元素不能是 sql 空值。 整个数组可以设置为空,但是你不能有这么一个数组,里面有些元素是空, 而有些不是。(这一点将来可能改变。)
前面的两个插入的结果看起来像这样:
SELECT * FROM sal_emp; name | pay_by_quarter | schedule -------+---------------------------+------------------------------------------- Bill | {10000,10000} | {{meeting,lunch},{training,presentation}} Carol | {20000,25000} | {{breakfast,consulting},{meeting,lunch}} (2 rows)
我们还可以使用ARRAY构造器语法:
INSERT INTO sal_emp VALUES ('Bill',ARRAY[10000,10000],ARRAY[['meeting','lunch'],['training','presentation']]); INSERT INTO sal_emp VALUES ('Carol',ARRAY[20000,25000],ARRAY[['breakfast','consulting'],['meeting','lunch']]);
请注意数组元素是普通的 sql 常量或者表达式;比如,字串文本是用单引号包围的, 而不是像数组文本那样用双引号。ARRAY构造器语法在Section 4.2.10里有更详细的讨论。