打印

PostgreSQL学习文档 8.0

8.11. 复合类型

复合类型描述一行或者一条记录的结构; 它实际上只是一个字段名和它们的数据类型的列表。 PostgreSQL 允许像简单数据类型那样使用复合类型。 比如,一个表的某个字段可以声明为一个复合类型。
8.11.1. 声明复合类型

下面是两个定义复合类型的简单例子:

CREATE TYPE complex AS (
    r       double precision,
    i       double precision
);

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

语法类似与 CREATE TABLE,只是这里只可以声明字段名字和类型; 目前不能声明约束(比如 NOT NULL 这样的)。请注意 AS 关键字是很重要的; 没有它,系统会认为这是完全不同的 CREATE TYPE 命令,因此你会看到奇怪的语法错误。

定义了类型,我们就可以用它创建表:

CREATE TABLE on_hand (
    item      inventory_item,
    count     integer
);

INSERT INTO on_hand VALUES (ROW('fuzzy dice', 42, 1.99), 1000);

或者函数:

CREATE FUNCTION price_extension(inventory_item, integer) RETURNS numeric
AS 'SELECT $1.price * $2' LANGUAGE SQL;

SELECT price_extension(item, 10) FROM on_hand;

在你创建表的时候,也会自动创建一个复合类型,名字与表名字相同,表示该表的复合类型。 比如,如果我们说过

CREATE TABLE inventory_item (
    name            text,
    supplier_id     integer REFERENCES suppliers,
    price           numeric CHECK (price > 0)
);

然后,和上面显示的相同的 inventory_item 复合类型也会作为副产品创建, 并且可以和上面一样使用。不过,需要注意目前的实现的一个重要限制:因为现在还没有约束和复合类型联结, 所以在表定义中显示的约束并不适用于表之外的复合类型。 (一个部分绕开的办法是使用域类型作为复合类型的成员。)
8.11.2. 复合类型值输入

要以文本常量书写复合类型值,在圆括弧里包围字段值并且用逗号分隔他们。 你可以在任何字段值周围放上双引号,如果值本身包含逗号或者圆括弧,你必须用双引号括起。 (更多细节见下面。)因此,复合类型常量的一般格式如下:

'( val1 , val2 , ... )'

一个例子是

'("fuzzy dice",42,1.99)'

如果 inventory_item 类型在前面已经定义了,那么这是一个合法的数值。 要让一个字段是空,那么在列表里它的位置上不要写任何字符。比如,下面这个常量在第三个字段声明一个 NULL:

'("fuzzy dice",42,)'

如果你想要一个空字串,而不是 NULL,写一对双引号:

'("",42,)'

这里的第一个字段是一个非 NULL 空字串,第三个字段是 NULL。

(这些常量实际上只是我们在 Section 4.1.2.5 讨论的一般类型常量的一个特殊例子。 这些常量一开始只是当作字串,然后传递给复合类型输入转换过程。一个明确的类型声明可能是必须的。)

我们也可以用 ROW 表达式语法来构造复合类型值。 在大多数场合下,这种方法都比用字串文本的语法更简单,因为你不用操心多重引号。 我们已经在上面使用了这种方法了:

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

只要你在表达式里有超过一个字段,那么关键字 ROW 就实际上是可选的, 所以可以简化为

('fuzzy dice', 42, 1.99)
('', 42, NULL)

ROW 表达式语法在Section 4.2.11 里有更详细的讨论。
8.11.3. 访问复合类型

要访问复合类型字段的一个域,我们写出一个点以及域的名字,非常类似从一个表名字里选出一个字段。 实际上,因为实在太像从表名字中选取字段,所以我们经常需要用圆括弧来避免分析器混淆。 比如,你可能需要从 on_hand 例子表中选取一些子域,像下面这样:

SELECT item.name FROM on_hand WHERE item.price > 9.99;

这样将不能工作,因为根据 SQL 语法, item 是从一个表名字选取的,而不是一个域名字。 你必须像下面这样写:

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

或者如果你也需要使用表名字(比如,在一个多表查询里),这么写:

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

现在圆括弧对象正确地解析为一个指向 item 字段的引用,然后就可以从中选取子域。

类似的语法问题适用于在任何地点从一个复合类型值中查询一个域。 比如,要从一个返回复合类型值的函数中只选许一个字段,你需要写像下面这样的东西

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

如果没有额外的圆括弧,会产生一个语法错误。
8.11.4. 修改复合类型

下面是一些插入和更新复合类型字段的正确语法。首先,插入或者更新整个字段:

INSERT INTO mytab (complex_col) VALUES((1.1,2.2));

UPDATE mytab SET complex_col = ROW(1.1,2.2) WHERE ...;

第一个例子省略了 ROW,第二个使用它;我们用哪种方法都行。

我们可以更新一个复合字段的独立子域:

UPDATE mytab SET complex_col.r = (complex_col).r + 1 WHERE ...;

请注意,这里我们不需要(实际上是不能)在 SET 后面出现的字段名周围放上圆括弧, 但是我们在等号右边的表达式里引用同一个字段的时候却需要圆括弧。

我们也可以声明子域是 INSERT 的目标:

INSERT INTO mytab (complex_col.r, complex_col.i) VALUES(1.1, 2.2);

如果我们没有为字段的所有子域提供数值,那么剩下的子域将用空值填充。
8.11.5. 复合类型输入和输出语法

一个复合类型的文本表现形式包含那些根据独立的子域类型各自 I/O 转换规则解析的项, 加上一些表明这是复合结构的修饰。这些修饰包括整个数值周围的圆括弧(( 和 )), 加上相邻域之间的逗号(,)。圆括弧外面的空白被忽略,但是在圆括弧里面, 它被当作子域数值的一部分,根据该子域的数据类型,这些空白可能有用,也可能没用。 比如,在

'(  42)'

里,如果子域类型是整数,那么空白将被忽略,但是如果是文本,那么就不会忽略。

如前面显示的那样,在给一个复合类型写数值的时候,你可以在独立的子域数值周围用双引号包围。 如果子域数值会导致复合数值分析器歧义,那么你必须这么做。 特别是子域包含圆括弧,逗号,双引号,或者反斜杠的场合,必须用双引号括起来。 要想在双引号括起来的子域数值里面放双引号,那么你需要在它前面放一个反斜杠。 (同样,在一个双引号括起的子域数值里面的一对双引号表示一个双引号字符,就像 SQL 字串文本的单引号规则一样。) 另外,你可以用反斜杠逃逸的方法保护所有可能会当作复合类型语法的数据字符。

一个完全空的子域数值(在逗号或者逗号与圆括弧之间没有字符)表示一个 NULL。 要写一个空字串,而不是一个 NULL,写 ""。

假如子域数值是空字串或者包含圆括弧,逗号,双引号,反斜杠或者空白,复合类型输出过程会在子域数值周围放上双引号。 (为空白这么处理不是必须的,但是可以增强易读性。)在一个子域数值里面嵌入的双引号和反斜杠将会写成两份。

    注意: 请注意你写得任何 SQL 命令都首先被当作字串文本解析,然后才当作复合类型。 这就加倍了你需要的反斜杠数目。比如,要插入一个包含双引号和一个反斜杠的 text 子域到一个复合类型数值里, 你需要写

    INSERT ... VALUES ('("\\"\\\\"');

    字串文本处理器先吃掉一层反斜杠,这样到大复合类型分析器的东西看起来像 ("\"\\"。 然后,字串填给 text 数据类型的输入过程,变成 "\。 (如果我们面对的数据类型还会对反斜杠另眼相看,比如 bytea, 那么我们可能需要在命令里多达八个反斜杠以获取在存储的复合类型子域中有一个反斜杠。) 美元符包围(参阅 Section 4.1.2.2)可以用于避免双份反斜杠的问题。

    提示: 在 SQL 命令里写复合类型值的时候,ROW 构造器通常比复合文本语法更容易使用。 在 ROW 里,独立的子域数值的写法和并非作为复合类型的成员书写的方法一样。

TOP

8.12. 对象标识符类型

PostgreSQL 在内部使用对象标识符(OID)作为各种系统表的主键。 同时,系统还给用户创建的表增加一个 OID 系统字段(除非在建表时声明了 WITHOUT OIDS 或者是配置参数 default_with_oids 设置成了假)。 类型 oid 代表一个对象标识符。除此以外还有几个 oid 的别名: regproc,regprocedure,regoper, regoperator,regclass,和 regtype。 Table 8-19 显示了概要。

目前 oid 类型是用一个无符号的四字节整数实现的。 因此,它是不够用于提供大数据库范围内的唯一性保证的, 甚至在单个的大表中也不行。因此,我们不鼓励在用户创建的表中使用 OID 字段做主键。OID 最好只是用于引用系统表。

    注意: 在 PostgreSQL 8.0.0 里,用户创建的表缺省时有 OID。 不过,这个行为在将来的 PostgreSQL 版本里很有可能改变。 最后,用户创建的表将不包括 OID 系统字段,除非在创建表的时候声明了 WITH OIDS, 或者配置参数 default_with_oids 设置为真。如果你的应用要求表里面有一个系统字段 OID, 那么应该在创建表的时候声明 WITH OIDS,以保证与将来的 PostgreSQL 版本兼容。

oid 类型本身除了比较之外还有几个操作。 不过,它可以转换为整数,然后用标准的整数操作符操作。(如果你这么干, 那么请注意可能的有符号和无符号之间的混淆。)

OID 别名类型没有自己的操作,除指明的输入和输出过程之外。 这些过程可以为系统对象接受和显示符号名,而不仅仅是类型 oid 将要使用的行数值。别名类型允许我们简化为对象查找 OID 值的过程。 比如,检查和一个表 mytable 相关的pg_attribute 行, 我们可以写

SELECT * FROM pg_attribute WHERE attrelid = 'mytable'::regclass;

而不用

SELECT * FROM pg_attribute
  WHERE attrelid = (SELECT oid FROM pg_class WHERE relname = 'mytable');

虽然看上去不坏,但是这个例子还是简化了好多,如果在不同的模式里有好多叫 mytable 的表,那么我们需要写一个更复杂的子查询。 regclass 的输入转换器处理根据模式路径设置的表检索工作,所以它自动干了"正确的事情"。 类似的还有,把一个表的 OID 转换成 regclass 是查找一个 OID 对应的符号名称的最简单方法。

Table 8-19. 对象标识类型
名字        引用        描述        数值例子
oid        任意        数字的对象标识符        564182
regproc        pg_proc        函数名字        sum
regprocedure        pg_proc        带参数类型的函数        sum(int4)
regoper        pg_operator        操作符名        +
regoperator        pg_operator        带参数类型的操作符        *(integer,integer)或者-(NONE,integer)
regclass        pg_class        关系名        pg_type
regtype        pg_type        数据类型名        integer

所有 OID 别名类型都接受有模式修饰的名字,并且如果在当前 搜索路径中,在不增加修饰的情况下无法找到该对象,那么在输出 时将显示有模式修饰的名字。regproc 和 regoper 别名类型将只接受唯一的输入名字(不能重载),因此它们的用途有限; 对于大多数应用,regprocedure 或 regoperat或者 更合适。对于 regoperat或者,单目操作符是通过在那些未用的操作数 上写NONE来标识的。

系统使用的另外一个标识符类型是 xid,或者说是事务(缩写xact) 标识符。它是系统字段 xmin 和 xmax 的 数据类型。事务标识符是 32 位的量。

系统需要的第三种标识符类型是 cid,或者命令标识符。 它是系统字段 cmin 和 cmax 的数据类型。 命令标识符也是 32 位的量。

系统使用的最后的标识符类型是 tid,或者说是元组标识符。 它是系统表字段 ctid 的数据类型。元组 ID 是一对儿数值 (块号,块内的元组索引),它标识该元组在其所在表内的物理位置。

(系统字段在 Section 5.2 里有更多解释。)

TOP

8.13. 伪类型

PostgreSQL 类型系统包含一系列特殊用途的 条目,它们按照类别来说叫做 伪类型。一个伪类型不能作为 字段的数据类型,但是它可以用于声明一个函数的参数或者结果类型。 每个可用的伪类型在一个函数不只是简单地接受并返回某种SQL数据类型的 情况下都很有用。 Table 8-20列出了现有的伪类型。

Table 8-20. 伪类型
名字        描述
any        表示一个函数接受任何输入数据类型
anyarray        表示一个函数接受任意数组数据类型(参阅 Section 31.2.5)
anyelement        标识一个函数接受任何数据类型(参阅 Section 31.2.5)。
cstring        表明一个函数接受或者返回一个空结尾的 C 字串
internal        表示一个函数接受或者返回一种服务器内部的数据类型
language_handler        一个过程语言调用句柄声明为返回 language_handler
void        表示一个函数不返回数值
record        标识一个函数返回一个未声明的行类型
trigger        一个触发器函数声明为返回 trigger
opaque        一个已经过时的类型,以前用于所有上面这些用途

用 C 编写的函数(不管是内置的还是动态装载的)都可以声明为接受或者返回 这样的伪数据类型。在把伪类型用做函数参数类型的时候,保证函数行为正常 就是函数作者的任务了。

用过程语言编写的函数只能根据它们的实现语言是否可以使用伪类型而使用 它。目前,过程语言都不允许使用伪类型作为参数类型,并且只允许使用 void 和 record 作为结果类型(如果函数用做触发器,那么加上 trigger)。 一些多态的函数还支持使用 anyarray 和anyelement类型。

伪类型 internal 用于声明那种只能在数据库系统内部调用的函数, 它们不能直接在SQL查询里调用。如果函数至少有一个 internal 类型 的参数,那么我们就不能从SQL里调用它。为了保留这个限制的类型安全, 我们一定要遵循这样的编码规则:不要创建任何声明为返回 internal 的函数,除非它至少有一个 internal 参数。

TOP

9.1. 逻辑操作符

常用的逻辑操作符有:

AND
OR
NOT

SQL 使用三值的布尔逻辑,这时空值代表"unknown"。 观察下面真值表:

a        b        a AND b        a OR b
TRUE        TRUE        TRUE        TRUE
TRUE        FALSE        FALSE        TRUE
TRUE        NULL        NULL        TRUE
FALSE        FALSE        FALSE        FALSE
FALSE        NULL        FALSE        NULL
NULL        NULL        NULL        NULL

a        NOT a
TRUE        FALSE
FALSE        TRUE
NULL        NULL

操作符 AND 和 OR 都是可交换的, 也就是说,你可以交换左右操作数而不影响结果。但是请参阅 Section 4.2.12 获取有关子表达式计算顺序的更多信息

TOP

9.2. 比较操作符

可用的比较操作符在 Table 9-1 显示。

Table 9-1. 比较操作符
操作符        描述
<         小于
>         大于
<=         小于或等于
>=         大于或等于
=         等于
<> 或 !=         不等于

    注意: != 操作符在分析器阶段被转换成 <>。把 != 和 <> 操作符实现为做不同的事是不可能的。

比较操作符可以用于所有可以比较的数据类型。 所有比较操作符都是双目操作符,返回 boolean 类型数值; 象1 < 2 < 3 这样的表达式是非法的 (因为没有什么 < 操作符用于 在布尔值和3之间做比较)。

除了比较操作符以外,我们还可以使用 BETWEEN 构造。

a BETWEEN x AND y

等效于

a >= x AND a <= y

类似的还有

a NOT BETWEEN x AND y

等效于

a < x OR a > y

这两种形式之间没有甚么区别,只不过第一种形式需要一些 CPU 周期在内部将它改写成第二种形式。

要检查一个值是否为 NULL,使用下面构造

expression IS NULL
expression IS NOT NULL

或者等效,但并不标准的构造

expression ISNULL
expression NOTNULL

不要 写 expression = NULL 因为 NULL 是不"等于" NULL 的。(NULL 代表一个未知的数值,因此我们无法知道两个未知的数值是否相等。) 这个行为遵循 SQL 标准。

    提示: 有些应用可能要求表达式 expression = NULL 在 expression 得出 NULL 值地时候返回真。 我们强烈建议这样的应用修改成遵循 SQL 标准。但是,如果这样修改是不可能的,那么我们可以使用配置变量 transform_null_equals。 如果打开它, PostgreSQL 将把 x = NULL 子句转换成 x IS NULL。 在 PostgreSQL 版本 6.5 到 7.1 之间,这是缺省的行为。

如果有任何一个输入是空,那么普通的比较操作符生成空(表示"未知")。 另外一个比较的方法是用 IS DISTINCT FROM 构造:

expression IS DISTINCT FROM expression

对于非空输入,这个与 <> 操作符相同。 但是,假如两个输入都是空,那么它将返回假,而如果只有一个输入是空,那么它将返回真。 这样就很有效地把空当作一个普通地数据值看待,而不是"未知"。

布尔数值可以用下面的构造进行测试

expression IS TRUE
expression IS NOT TRUE
expression IS FALSE
expression IS NOT FALSE
expression IS UNKNOWN
expression IS NOT UNKNOWN

这些构造将总是返回真或假,从来不返回空值,即使操作数是空也如此。 空值输入被当做逻辑数值"未知"。 请注意实际上 IS UNKNOWN 和 IS NOT UNKNOWN 分别与 IS NULL 和 IS NOT NULL 相同, 只是输入表达式必须是布尔类型。

TOP

9.3. 数学函数和操作符

PostgreSQL 为许多类型提供了数学操作符。 对于那些在所有可能的组合中都没有一般的数学传统的类型 (比如,日期/时间类型),我们在随后的章节里描述实际的行为。

Table 9-2 显示了可用的数学操作符。

Table 9-2. 数学操作符
操作符        描述        例子        结果
+         加        2 + 3        5
-         减        2 - 3        -1
*         乘        2 * 3        6
/         除 (整数除法将截断结果)        4 / 2        2
%         模除 (求余)        5 % 4        1
^         幂(指数运算)        2.0 ^ 3.0        8
|/         平方根        |/ 25.0        5
||/         立方根        ||/ 27.0        3
!         阶乘        5 !        120
!!         阶乘 (前缀作符)        !! 5        120
@         绝对值        @ -5.0        5
&         二进制 AND        91 & 15        11
|         二进制 OR        32 | 3        35
#         二进制 XOR        17 # 5        20
~         二进制 NOT        ~1        -2
<<         二进制左移        1 << 4        16
>>         二进制右移        8 >> 2        2

按位操作操作符只能用于整数数据类型,而其它的操作符可以用于全部数值数据类型。 按位操作的操作符还可以用于位串类型 bit 和 bit varying, 如 Table 9-10 所示。

Table 9-3 显示了可用的数学函数。 在该表中,dp 表示double precision。 这些函数中有许多都有多种不同的形式,区别是参数不同。 除非特别指明,任何特定形式的函数都返回和它的参数相同的数据类型。 处理 double precision 数据的函数大多数是在 宿主系统的 C 库的基础上实现的;因此,准确度和 数值范围方面的行为是根据宿主系统而变化的。

Table 9-3. 数学函数
函数        返回类型        描述        例子        结果
abs(x)        (和x类型相同)        绝对值        abs(-17.4)        17.4
cbrt(dp)        dp        立方根        cbrt(27.0)        3
ceil(dp 或者 numeric)        与输入相同        不小于参数的最小的整数        ceil(-42.8)        -42
ceiling(dp or numeric)        (与输入相同)        不小于参数的最小整数(ceil 的别名)        ceiling(-95.3)        -95
degrees(dp)        dp        把弧度转为角度        degrees(0.5)        28.6478897565412
exp(dp 或 numeric)        与输入相同        自然指数        exp(1.0)        2.71828182845905
floor(dp 或 numeric)        与输入相同        不大于参数的最大整数        floor(-42.8)        -43
ln(dp 或 numeric)        与输入相同        自然对数        ln(2.0)        0.693147180559945
log(dp 或 numeric)        与输入相同        10 为底的对数        log(100.0)        2
log(b numeric, x numeric)        numeric        指定底数的对数        log(2.0, 64.0)        6.0000000000
mod(y, x)        (和参数类型相同)        除法 y/x 的余数(模)        mod(9,4)        1
pi()        dp        "π" 常量        pi()        3.14159265358979
power(a dp, b dp)        dp        求a的 b 次幂        power(9.0, 3.0)        729
power(a numeric, b numeric)        numeric        求a的 b 次幂        power(9.0, 3.0)        729
radians(dp)        dp        把角度转为弧度        radians(45.0)        0.785398163397448
random()        dp        0.0 到 1.0 之间的随机数值        random()         
round(dp 或者 numeric)        (与输入相同)        圆整为最接近的整数        round(42.4)        42
round(v numeric, s integer)        numeric        圆整为s位小数数字        round(42.4382, 2)        42.44
setseed(dp)        integer        为随后的 random() 调用设置种子        setseed(0.54823)        1177314959
sign(dp 或者 numeric)        (和输入相同)        参数的符号(-1, 0, +1)        sign(-8.4)        -1
sqrt(dp 或者 numeric)        (和输入相同)        平方根        sqrt(2.0)        1.4142135623731
trunc(dp 或者 numeric)        (和输入相同)        截断(向零靠近)        trunc(42.8)        42
trunc(v numeric, s integer)        numeric        截断为 s 小数位置的数字        trunc(42.4382, 2)        42.43
width_bucket(op numeric, b1 numeric, b2 numeric, count integer)        integer        返回一个桶,这个桶是在一个有 count 个桶, 上界为 b1,下界为 b2 的等深柱图中 operand 将被赋予的那个桶。         width_bucket(5.35, 0.024, 10.06, 5)        3

最后,Table 9-4 显示了可用的三角函数。 所有三角函数都有类型为 double precision 的参数和返回类型。

Table 9-4. 三角函数
函数        描述
acos(x)        反余弦
asin(x)        反正弦
atan(x)        反正切
atan2(x, y)        正切 y/x 的反函数
cos(x)        余弦
cot(x)        余切
sin(x)        正弦
tan(x)        正切

TOP

9.4. 字符串函数和操作符

本节描述了用于检查和操作字符串数值的函数和操作符。 在这个环境中的字串包括所有类型 character, character varying,和 text 的值。除非另外说明,所有下面列出的函数都可以处理这些类型, 不过要小心的是,在使用 character 类型的时候, 它的自动填充的潜在影响。通常这里描述的函数也能用于非字串 类型,我们只要先把那些数据转化为字串表现形式就可以了。 有些函数还可以处理位串类型。

SQL 定义了一些字串函数, 它们有指定的语法,它们里面是用 某种特定的关键字,而不是逗号来分隔参数。 详情请见Table 9-5, 这些函数也用正常的函数调用说法实现了。 (参阅 Table 9-6。)

Table 9-5. SQL 字串函数和操作符
函数        返回类型        描述        例子        结果
string || string        text         字串连接         'Post' || 'greSQL'        PostgreSQL
bit_length(string)        integer        字串里二进制位的个数        bit_length('jose')        32
char_length(string) 或 character_length(string)        integer        字串中的字符个数         char_length('jose')        4
convert(string using conversion_name)        text        使用指定的转换名字改变编码。转换可以通过 CREATE CONVERSION 定义。当然系统里有一些预定义的转换名字。参阅 Table 9-7 获取可用的转换名。         convert('PostgreSQL' using iso_8859_1_to_utf_8)        Unicode (UTF-8) 编码的'PostgreSQL'
lower(string)        text        把字串转化为小写        lower('TOM')        tom
octet_length(string)        integer        字串中的字节数        octet_length('jose')        4
position(substring in string)        integer        声明的子字串的位置        position('om' in 'Thomas')        3
overlay(string placing string from integer [for integer])        text        替换子字串         overlay('Txxxxas' placing 'hom' from 2 for 4)        Thomas
position(substring in string)        integer        指定的子字串的位置        position('om' in 'Thomas')        3
substring(string [from integer] [for integer])        text        抽取子字串         substring('Thomas' from 2 for 3)        hom
substring(string from pattern)        text        抽取匹配 POSIX 正则表达式的子字串         substring('Thomas' from '...$')        mas
substring(string from pattern for escape)        text        抽取匹配SQL正则表达式的子字串         substring('Thomas' from '%#"o_a#"_' for '#')        oma
trim([leading | trailing | both] [characters] from string)         text        从字串 string 的 开头/结尾/两边/ 删除只包含 characters (缺省是一个空白)的最长的字串。         trim(both 'x' from 'xTomxx')        Tom
upper(string)        text        把字串转化为大写。        upper('tom')        TOM

还有额外的字串操作函数可以用,它们在Table 9-6列出。 它们有些在内部用于实现Table 9-5列出的SQL标准字串函数。

Table 9-6. 其他字串函数
函数        返回类型        描述        例子        结果
ascii(text)        integer        参数第一个字符的 ASCII 码        ascii('x')        120
btrim(string text [, characters text])        text        从 string 开头和结尾删除只包含在 characters 里(缺省是空白)的字符的最长字串。         btrim('xyxtrimyyx','xy')        trim
chr(integer)        text        给出 ASCII 码的字符        chr(65)        A
convert(string text, [src_encoding name,] dest_encoding name)         text        把字串转换为 dest_encoding . 原来的编码是用 src_encoding 声明的. 如果省略了 src_encoding, 则假设为数据库编码.         convert('text_in_unicode', 'UNICODE', 'LATIN1')        以 ISO 8859-1 编码表示的text_in_unicode
decode(string text, type text)         bytea        把早先用encode编码的,存放在 string 里面的二进制数据解码。 参数类型和encode一样。         decode('MTIzAAE=', 'base64')        123\000\001
encode(data bytea, type text)         text        把二进制数据编码为只包含 ASCII 形式的数据。 支持的类型有base64,hex,escape。         encode('123\\000\\001', 'base64')        MTIzAAE=
initcap(text)        text        把每个单词的第一个子母转为大写,其它的保留小写。 单词是一系列字母数字组成的字符,用非字母数字分隔。         initcap('hi thomas')        Hi Thomas
length(string text)        integer        string 中字符的数目         length('jose')        4
lpad(string text, length integer [, fill text])         text        通过填充字符 fill (缺省时为空白), 把 string 填充为长度 length。 如果 string 已经比 length 长则将其截断(在右边)。         lpad('hi', 5, 'xy')        xyxhi
ltrim(string text [, characters text])         text        从字串 string 的 开头删除只包含 characters (缺省是一个空白)的最长的字串。         ltrim('zzzytrim','xyz')        trim
md5(string text)        text        计算给出 string 的 MD5 散列,以十六进制返回结果。         md5('abc')        900150983cd24fb0d6963f7d28e17f72
pg_client_encoding()        name        当前客户端编码名称。         pg_client_encoding()        SQL_ASCII
quote_ident(string text)        text        返回给出字串的一个适用于在SQL语句字串里当作标识符引起使用的形式。 只有在必要的时候才会添加引号(也就是说,如果字串包含非标识符字符或者会转换大小写的字符)。 嵌入的引号被恰当地写了双份。         quote_ident('Foo bar')        "Foo bar"
quote_literal(string text)        text        返回给出字串的一个适用于在SQL语句字串里当作文本使用的形式。 嵌入的引号和反斜杠被恰当地写了双份。         quote_literal('O\'Reilly')        'O''Reilly'
repeat(string text, number integer)        text        重复 string number 次。        repeat('Pg', 4)        PgPgPgPg
replace(string text, from text, to text)        text        把字串string里出现地所有子字串 from 替换成子字串 to。         replace('abcdefabcdef', 'cd', 'XX')        abXXefabXXef
rpad(string text, length integer [, fill text])         text        通过填充字符 fill (缺省时为空白), 把 string 填充为长度 length。 如果 string 已经比 length 长则将其截断。         rpad('hi', 5, 'xy')        hixyx
rtrim(string text [, character text])         text        从字串 string 的 结尾删除只包含 character (缺省是个空白)的最长的字串。         rtrim('trimxxxx','x')        trim
split_part(string text, delimiter text, field integer)        text        根据 delimiter 分隔 string 返回生成的第 field 个子字串(一为基)。         split_part('abc~@~def~@~ghi','~@~',2)        def
strpos(string, substring)        text        声明的子字串的位置。(和 position(substring in string一样),不过要注意参数顺序 是相反的)         strpos('high','ig')        2
substr(string, from [, count])        text        抽取子字串。(和 substring(string from from for count)一样)         substr('alphabet', 3, 2)        ph
to_ascii(text [, encoding])        text        把 text 从其它编码转换为 ASCII。 [a]         to_ascii('Karel')        Karel
to_hex(number integer 或者 bigint)        text        把 number 转换成其对应地十六进制表现形式。         to_hex(9223372036854775807)        7fffffffffffffff
translate(string text, from text, to text)         text        把在 string 中包含的任何匹配 from 中的字符的字符转化为对应的 在 to 中的字符。         translate('12345', '14', 'ax')        a23x5
Notes:
a. to_ascii 函数只支持从 LATIN1, LATIN2,LATIN9 和 WIN1250 编码进行转换。

TOP

Table 9-7. 内置的转换
转换名 [a]         源编码        目的编码
ascii_to_mic        SQL_ASCII        MULE_INTERNAL
ascii_to_utf_8        SQL_ASCII        UNICODE
big5_to_euc_tw        BIG5        EUC_TW
big5_to_mic        BIG5        MULE_INTERNAL
big5_to_utf_8        BIG5        UNICODE
euc_cn_to_mic        EUC_CN        MULE_INTERNAL
euc_cn_to_utf_8        EUC_CN        UNICODE
euc_jp_to_mic        EUC_JP        MULE_INTERNAL
euc_jp_to_sjis        EUC_JP        SJIS
euc_jp_to_utf_8        EUC_JP        UNICODE
euc_kr_to_mic        EUC_KR        MULE_INTERNAL
euc_kr_to_utf_8        EUC_KR        UNICODE
euc_tw_to_big5        EUC_TW        BIG5
euc_tw_to_mic        EUC_TW        MULE_INTERNAL
euc_tw_to_utf_8        EUC_TW        UNICODE
gb18030_to_utf_8        GB18030        UNICODE
gbk_to_utf_8        GBK        UNICODE
iso_8859_10_to_utf_8        LATIN6        UNICODE
iso_8859_13_to_utf_8        LATIN7        UNICODE
iso_8859_14_to_utf_8        LATIN8        UNICODE
iso_8859_15_to_utf_8        LATIN9        UNICODE
iso_8859_16_to_utf_8        LATIN10        UNICODE
iso_8859_1_to_mic        LATIN1        MULE_INTERNAL
iso_8859_1_to_utf_8        LATIN1        UNICODE
iso_8859_2_to_mic        LATIN2        MULE_INTERNAL
iso_8859_2_to_utf_8        LATIN2        UNICODE
iso_8859_2_to_windows_1250        LATIN2        WIN1250
iso_8859_3_to_mic        LATIN3        MULE_INTERNAL
iso_8859_3_to_utf_8        LATIN3        UNICODE
iso_8859_4_to_mic        LATIN4        MULE_INTERNAL
iso_8859_4_to_utf_8        LATIN4        UNICODE
iso_8859_5_to_koi8_r        ISO_8859_5        KOI8
iso_8859_5_to_mic        ISO_8859_5        MULE_INTERNAL
iso_8859_5_to_utf_8        ISO_8859_5        UNICODE
iso_8859_5_to_windows_1251        ISO_8859_5        WIN
iso_8859_5_to_windows_866        ISO_8859_5        ALT
iso_8859_6_to_utf_8        ISO_8859_6        UNICODE
iso_8859_7_to_utf_8        ISO_8859_7        UNICODE
iso_8859_8_to_utf_8        ISO_8859_8        UNICODE
iso_8859_9_to_utf_8        LATIN5        UNICODE
johab_to_utf_8        JOHAB        UNICODE
koi8_r_to_iso_8859_5        KOI8        ISO_8859_5
koi8_r_to_mic        KOI8        MULE_INTERNAL
koi8_r_to_utf_8        KOI8        UNICODE
koi8_r_to_windows_1251        KOI8        WIN
koi8_r_to_windows_866        KOI8        ALT
mic_to_ascii        MULE_INTERNAL        SQL_ASCII
mic_to_big5        MULE_INTERNAL        BIG5
mic_to_euc_cn        MULE_INTERNAL        EUC_CN
mic_to_euc_jp        MULE_INTERNAL        EUC_JP
mic_to_euc_kr        MULE_INTERNAL        EUC_KR
mic_to_euc_tw        MULE_INTERNAL        EUC_TW
mic_to_iso_8859_1        MULE_INTERNAL        LATIN1
mic_to_iso_8859_2        MULE_INTERNAL        LATIN2
mic_to_iso_8859_3        MULE_INTERNAL        LATIN3
mic_to_iso_8859_4        MULE_INTERNAL        LATIN4
mic_to_iso_8859_5        MULE_INTERNAL        ISO_8859_5
mic_to_koi8_r        MULE_INTERNAL        KOI8
mic_to_sjis        MULE_INTERNAL        SJIS
mic_to_windows_1250        MULE_INTERNAL        WIN1250
mic_to_windows_1251        MULE_INTERNAL        WIN
mic_to_windows_866        MULE_INTERNAL        ALT
sjis_to_euc_jp        SJIS        EUC_JP
sjis_to_mic        SJIS        MULE_INTERNAL
sjis_to_utf_8        SJIS        UNICODE
tcvn_to_utf_8        TCVN        UNICODE
uhc_to_utf_8        UHC        UNICODE
utf_8_to_ascii        UNICODE        SQL_ASCII
utf_8_to_big5        UNICODE        BIG5
utf_8_to_euc_cn        UNICODE        EUC_CN
utf_8_to_euc_jp        UNICODE        EUC_JP
utf_8_to_euc_kr        UNICODE        EUC_KR
utf_8_to_euc_tw        UNICODE        EUC_TW
utf_8_to_gb18030        UNICODE        GB18030
utf_8_to_gbk        UNICODE        GBK
utf_8_to_iso_8859_1        UNICODE        LATIN1
utf_8_to_iso_8859_10        UNICODE        LATIN6
utf_8_to_iso_8859_13        UNICODE        LATIN7
utf_8_to_iso_8859_14        UNICODE        LATIN8
utf_8_to_iso_8859_15        UNICODE        LATIN9
utf_8_to_iso_8859_16        UNICODE        LATIN10
utf_8_to_iso_8859_2        UNICODE        LATIN2
utf_8_to_iso_8859_3        UNICODE        LATIN3
utf_8_to_iso_8859_4        UNICODE        LATIN4
utf_8_to_iso_8859_5        UNICODE        ISO_8859_5
utf_8_to_iso_8859_6        UNICODE        ISO_8859_6
utf_8_to_iso_8859_7        UNICODE        ISO_8859_7
utf_8_to_iso_8859_8        UNICODE        ISO_8859_8
utf_8_to_iso_8859_9        UNICODE        LATIN5
utf_8_to_johab        UNICODE        JOHAB
utf_8_to_koi8_r        UNICODE        KOI8
utf_8_to_sjis        UNICODE        SJIS
utf_8_to_tcvn        UNICODE        TCVN
utf_8_to_uhc        UNICODE        UHC
utf_8_to_windows_1250        UNICODE        WIN1250
utf_8_to_windows_1251        UNICODE        WIN
utf_8_to_windows_1256        UNICODE        WIN1256
utf_8_to_windows_866        UNICODE        ALT
utf_8_to_windows_874        UNICODE        WIN874
windows_1250_to_iso_8859_2        WIN1250        LATIN2
windows_1250_to_mic        WIN1250        MULE_INTERNAL
windows_1250_to_utf_8        WIN1250        UNICODE
windows_1251_to_iso_8859_5        WIN        ISO_8859_5
windows_1251_to_koi8_r        WIN        KOI8
windows_1251_to_mic        WIN        MULE_INTERNAL
windows_1251_to_utf_8        WIN        UNICODE
windows_1251_to_windows_866        WIN        ALT
windows_1256_to_utf_8        WIN1256        UNICODE
windows_866_to_iso_8859_5        ALT        ISO_8859_5
windows_866_to_koi8_r        ALT        KOI8
windows_866_to_mic        ALT        MULE_INTERNAL
windows_866_to_utf_8        ALT        UNICODE
windows_866_to_windows_1251        ALT        WIN
windows_874_to_utf_8        WIN874        UNICODE
Notes:
a. 转换名遵循一个标准的命名模式:将源编码中的所有非字母数字字符 用下划线替换,后面跟着 _to_,然后后面再跟着 经过同样处理的目标编码的名字。因此这些名字可能和客户的编码名字 不同。

TOP

9.5. 二进制字串函数和操作符

本节描述那些检查和操作类型为 bytea 的数值的函数和操作符。

SQL 定义了一些有特殊语法的字串函数, 在这些函数里使用特殊关键字而不是逗号来分隔参数。 详情请见 Table 9-8。 一些函数也实现了使用常用语法进行函数调用的方法。 (参阅 Table 9-9。)

Table 9-8. SQL 二进制字串函数和操作符
函数        返回类型        描述        例子        结果
string || string        bytea         字串连接         '\\\\Post'::bytea || '\\047gres\\000'::bytea        \\Post'gres\000
octet_length(string)        integer        二进制字串中的字节数目        octet_length('jo\\000se'::bytea)        5
position(substring in string)        integer        指定子字串的位置        position('\\000om'::bytea in 'Th\\000omas'::bytea)        3
substring(string [from integer] [for integer])        bytea        抽取子字串         substring('Th\\000omas'::bytea from 2 for 3)        h\000o
trim([both] bytes from string)         bytea        从 string 的开头和结尾删除 只包含 bytes 的最长的字串。         trim('\\000'::bytea from '\\000Tom\\000'::bytea)        Tom
get_byte(string, offset)        integer        从字串中抽取字节。         get_byte('Th\\000omas'::bytea, 4)        109
set_byte(string, offset, newvalue)        bytea        设置字串中的字节。         set_byte('Th\\000omas'::bytea, 4, 64)        Th\000o@as
get_bit(string, offset)        integer        从字串中抽取位。         get_bit('Th\\000omas'::bytea, 45)        1
set_bit(string, offset, newvalue)        bytea        设置字串中的位。         set_bit('Th\\000omas'::bytea, 45, 0)        Th\000omAs

还有一些二进制字串处理函数可以使用,在Table 9-9列出。 其中有一些是在内部使用,用于实现Table 9-8列出的 SQL 标准的字串函数的。

Table 9-9. 其它二进制字串函数
函数        返回类型        描述        例子        结果
btrim(string bytea, bytes bytea)        bytea        从 string 的开头和结尾删除(截断) 只包含在 bytes 里面的字节的最长的字串。         btrim('\\000trim\\000'::bytea,'\\000'::bytea)        trim
length(string)        integer        二进制字串的长度         length('jo\\000se'::bytea)        5
decode(string text, type text)         bytea        把前面用encode()编码的放在 string 里的 二进制字串解码。参数类型和encode()里的一样。         decode('123\\000456', 'escape')        123\000456
encode(string bytea, type text)         text        把二进制字串编码为只包含 ASCII 的表现形式。 类型是∶ base64,hex,escape。         encode('123\\000456'::bytea, 'escape')        123\000456

TOP

9.6. 位串函数和操作符

本节描述用于检查和操作位串的函数和操作符,也就是操作类型为 bit 和 bit varying 的数值的函数和操作符。除了常用的比较操作符之外,还可以使用 Table 9-10 里显示的操作符。 &,|,和 # 的位串操作数必须等长。 在移位的时候,保留原始的位串的的长度,如例子所示。

Table 9-10. 位串操作符
操作符        描述        例子        结果
||         连接        B'10001' || B'011'        10001011
&         按位 AND(与)        B'10001' & B'01101'        00001
|         按位 OR(或)        B'10001' | B'01101'        11101
#         按位 XOR(异或)        B'10001' # B'01101'        11100
~         按位 NOT(非)        ~ B'10001'        01110
<<         按位左移        B'10001' << 3        01000
>>         按位右移        B'10001' >> 2        00100

下面的 SQL 标准函数除了可以用于字符串之外,也可以用于位串: length, bit_length, octet_length, position, substring。

另外,我们可以在整数和 bit 之间来回转换。例子:

44::bit(10)                    0000101100
44::bit(3)                     100
cast(-44 as bit(12))           111111010100
'1110'::bit(4)::integer        14

请注意,如果只是转换为 "bit",意思是转换成 bit(1), 因此只会转换成整数的最低位。

    注意: 在 PostgreSQL 8.0 以前,把一个整数转换成 bit(n) 将拷贝整数的最左边的 n 位, 而现在是拷贝最右边的 n 位。还有,把一个整数转换成比整数本身长位串,就会在最左边扩展符号。

TOP


感谢一直以来您对我们的支持!
当前时区 GMT+8, 现在时间是 2008-12-3 03:51 京ICP证060528 号

Designed By 17DST