============  值存储 ============ .. container:: sect1 :name: TYPECONV-QUERY .. container:: titlepage .. container:: .. container:: .. rubric:: 值存储 :name: 值存储 :class: title 将被插入到一个表的值会按照下列步骤被转换到目标列的数据类型。 .. container:: procedure :name: id-1.5.9.9.3 **值存储类型转换** 1. 检查一个与目标的准确匹配。 2. 否则,尝试转换表达式为目标类型。如果在两种类型之间的一个 *赋值造型*\ 已经被注册在\ ``pg_cast`` 目录(见\ `CREATE CAST `__\ )中, 这是可能的。或者,如果该表达式是一个未知类型的文字, 则该文字串的内容将被提供给目标类型的输入转换例程。 3. 检查是否有一个用于目标类型的尺寸调整造型。尺寸调整造型是一个从该类型到其自身的造型。 如果在\ ``pg_cast``\ 目录中找到一个,那么把表达式存储到目标列中之前把它应用到表达式。这样一个造型的实现函数总是采用一个额外的\ ``integer``\ 类型的参数,它接收目标列的\ ``atttypmod``\ 值(通常是它被声明的长度,尽管对于不同数据类型\ ``atttypmod``\ 有不同的解释),并且它可能采用第三个\ ``boolean``\ 参数来说明造型是显式的还是隐式的。该造型函数负责应用任何长度相关的语义,例如尺寸检查或截断。 .. container:: example :name: id-1.5.9.9.4 **例 character 存储类型转换** .. container:: example-contents 对于一个声明为\ ``character(20)``\ 的目标列,下面的语句展示了被存储的值如何被正确地调整尺寸: .. code:: screen CREATE TABLE vv (v character(20)); INSERT INTO vv SELECT 'abc' || 'def'; SELECT v, octet_length(v) FROM vv; v | octet_length ----------------------+-------------- abcdef | 20 (1 row) 实际发生的事情是两个未知文字被默认决定为\ ``text``\ ,允许\ ``||``\ 操作符被决定为\ ``text``\ 连接。 然后操作符的\ ``text``\ 结果被转换成\ ``bpchar``\ (“空白填充字符”,\ ``character``\ 数据类型的内部名称)来匹配目标列类型(由于从\ ``text``\ 到\ ``bpchar``\ 的转换是二进制强制的,这个转换不会插入任何实际的函数调用)。最后,尺寸调整函数\ ``bpchar(bpchar, integer, boolean)``\ 被从系统目录中找到并应用到操作符的结果和存储的列长度上。这个类型相关的函数执行必要的长度检查并增加填充的空间。