5.pgsql类型转换
-- 1.在系统表中⾥只有⼀个指数操作符,它以 double precision 作为参数。
-- 扫描器给下⾯查询表达式的两个参数赋予 integer 的初始类型:
SELECT 2 ^ 3 AS "exp";
-- 分析器对两个参数都做类型转换,查询等效于:
SELECT CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "exp";
-- 2.字符串连接操作符类型分析
-- ⼀种字符串风格的语法既可以⽤于字符串也可以⽤于复杂的扩展类型。未声明类型的字符串将被所有可能的候选操作符匹配。SELECT 'abc'::text || 'def' AS "text and unknown";
-- 因为查询中没有声明任何类型,所以本例中对类型没有任何初始提⽰。
-- 因此,分析器查所有候选操作符,发现既存在接受字符串类型范畴的操作符也存在接受位串类型范畴的操作符。
-- 因为字符串类型范畴是⾸选,所以选择字符串类型范畴的⾸选类型 text 作为解析未知类型⽂本的声明类型。
SELECT 'abc' || 'def' AS "unspecified";
-- 3.绝对值和取反操作符类型分析
-- 此处,系统在应⽤选定的操作符之前执⾏类⼀次 text 到 float8 的隐式转换。
SELECT @ '-4.5' AS "abs";
-- 我们可以验证它是 float8 ⽽不是其它类型:
SELECT @ '-4.5e500' AS "abs"; -- ERROR: 错误: "-4.5e500" 超出双精度类型的范围
-- 另⼀⽅⾯,前缀操作符 ~(按位取反)只为整数数据类型定义,⽽不为 float8 定义。因此,如果我们⽤ ~ 做类似的实验将得到:SELECT ~ '20' AS "negation"; -- HINT: ⽆法选择最佳候选操作符. 您也许需要增加显式的类型转换.
SELECT ~ CAST('20' AS int8) AS "negation";
-
- 4.圆整函数参数类型解析
SELECT round(4, 4); -- 48mesc
-- 因为带⼩数点的数值常量初始时被赋予 numeric 类型,因此下⾯的查询将不需要类型转换,并且可能会略微⾼效⼀些:
-- 实际上它被分析器转换成:
-- SELECT round(CAST (4 AS numeric), 4);
-- 因为带⼩数点的数值常量初始时被赋予 numeric 类型,因此下⾯的查询将不需要类型转换,并且可能会略微⾼效⼀些:
SELECT round(4.0, 4);-- 43mesc
-- 5.⼦字符串函数类型解析
SELECT substr('1234', 3); -- 34
-- 被分析器转换后实际上变成:
SELECT substr(CAST (varchar '1234' AS text), 3);
-- 【注意】分析器从 pg_cast 表中了解到 text 和 varchar 是⼆进制兼容的,意思是说⼀个可以传递给接受另⼀个的函数⽽不需要做任何物理转换。因此,在这种情况下,实际上没有做任何明确的类型转换。
-- ⽽且,如果以 integer 为参数调⽤函数,分析器将试图将其转换成 text 类型:
SELECT substr(1234, 3); -- 结果也为34
-- 实际上是这样执⾏的:
sql语句查询结果取反-- SELECT substr(CAST (1234 AS text), 3);
-- 这种⾃动转换能够成功是因为存在⼀个从 integer 到 text 的隐含转换可以调⽤。
-- 6.值存储(要插⼊表中的数值也根据下⾯的步骤转换成⽬标列的数据类型。)
-- 值存储数据类型解析规则
-- 6.1查与⽬标字段准确的匹配。
-- 6.2试着将表达式直接转换成⽬标类型。如果已知这两种类型之间存在⼀个已注册的转换函数,那么直接调⽤该转换函数即可。如果表达式是⼀个未知类型⽂本,该⽂本字符串的内容将交给⽬标类型的输⼊转换过程。
-- 6.3检查⼀下看看⽬标类型是否有长度转换。长度转换是⼀个从某类型到⾃⾝的转换。如果在 pg_cast 表⾥⾯到⼀个,那么在存储到⽬标字段之前先在表达式上应⽤。这样的转换函数总是接受⼀个额外的类型为 integer 的参数,它接收⽬标字段的声明长度(实际上是其 atttypmod 值,atttypmod 的解释随不同的数据类型⽽不同)。转换函数负责施加那些长度相关的语义,⽐如长度检查或者截断。
-- 对⼀个⽬标列定义为 character(20) 的语句,下⾯的语句确保存储值的长度正确:
-- 对⼀个⽬标列定义为 character(20) 的语句,下⾯的语句确保存储值的长度正确:
CREATE TABLE vv (v character(20));
INSERT INTO vv SELECT 'abc' || 'def';
SELECT v, length(v) FROM vv; -- abcdef 6
-- 这⾥真正发⽣的事情是两个 unknown ⽂本缺省解析成 text ,这样就允许 || 操作符解析成 text 连接。
-- 然后操作符的 text 结果转换成 bpchar("空⽩填充的字符型",character 类型内部名称)以匹配⽬标字段类型。
-- 不过,因为知道 text 和 bpchar 是⼆进制兼容的,这样的转换是隐含的并且实际上不做任何函数调⽤。
-- 最后,在系统表⾥到长度转换函数 bpchar(bpchar, integer) 并且应⽤于该操作符的结果并存储字段长。这个类型相关的函数执⾏所需的长度检查和额外的空⽩填充。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论