CREATE CAST
CREATE CAST — 定义一个新的转换
大纲
CREATE CAST (sourcetypeAStargettype) WITH FUNCTIONfuncname(argtype) [ AS ASSIGNMENT | AS IMPLICIT ] CREATE CAST (sourcetypeAStargettype) WITHOUT FUNCTION [ AS ASSIGNMENT | AS IMPLICIT ]
描述
CREATE CAST 定义一个新的转换。转换指定如何执行两种数据类型之间的转换。例如,
SELECT CAST(42 AS text);
通过调用一个先前指定的函数(这里是
text(int4))把整数常量 42 转换为
text 类型。(如果没有定义合适的转换,该转换失败。)
两种类型可以是二进制兼容的,这意味着它们可以“免费”地互相转换而无需调用任何函数。这要求相应的值使用相同的内部表示。例如,text 和 varchar 类型是二进制兼容的。
默认情况下,一个转换只能在显式转换请求中被调用,也就是显式的 CAST(、x AS
typename)x::typename 或
typename(x) 构造。
如果转换被标记为 AS ASSIGNMENT,那么在向目标数据类型的列赋值时它可以被隐式调用。例如,假设 foo.f1 是一个
text 类型的列,那么
INSERT INTO foo (f1) VALUES (42);
只有在从 integer 类型到
text 类型的转换被标记为 AS ASSIGNMENT 时才是允许的,否则不允许。(我们通常用赋值转换这个术语来描述这种转换。)
如果转换被标记为 AS IMPLICIT,那么它在任何上下文中都可以被隐式调用,无论是赋值还是表达式内部。例如,由于
|| 接受
text 操作数,
SELECT 'The time is ' || now();
只有在从 timestamp 到
text 的转换被标记为 AS IMPLICIT 时才允许。否则就必须显式写出转换,例如
SELECT 'The time is ' || CAST(now() AS text);
(我们通常用隐式转换这个术语来描述这种转换。)
在把转换标记为隐式方面明智的做法是保守。过多的隐式转换路径可能导致
PostgreSQL 对命令做出令人惊讶的解释,或者因为存在多种可能的解释而完全无法解析命令。一个好的经验法则是在同一通用类型类别中的类型之间,只让保持信息的转换可以隐式调用。例如,从 int2 到
int4 的转换可以合理地隐式,但从
float8 到 int4 的转换或许应该只用于赋值。跨类型类别的转换,例如从
text 到 int4,最好只用于显式转换。
要能创建一个转换,你必须拥有源数据类型或目标数据类型。要创建一个二进制兼容的转换,你必须是超级用户。(这个限制是因为一个错误的二进制兼容转换很容易使服务器崩溃。)
参数
sourcetype转换的源数据类型的名称。
targettype转换的目标数据类型的名称。
funcname(argtype)用来执行该转换的函数。函数名可以带模式限定。如果不带,该函数将在路径中查找。参数类型必须与源类型相同,结果数据类型必须与该转换的目标类型匹配。
WITHOUT FUNCTION表示源类型和目标类型是二进制兼容的,因此不需要函数来执行该转换。
AS ASSIGNMENT表示该转换可以在赋值上下文中被隐式调用。
AS IMPLICIT表示该转换可以在任何上下文中被隐式调用。
注意
使用 DROP CAST 删除用户定义的转换。
记住,如果你希望能够双向转换类型,需要显式地在两个方向上声明转换。
在
PostgreSQL 7.3 之前,每个与某个数据类型同名、返回该数据类型并且接受一个不同类型参数的函数都自动是一个转换函数。面对模式(schema)的引入以及为了能在系统目录中表示二进制兼容的转换,这一约定已被放弃。(内建的转换函数仍然遵循这一命名方案,但现在它们必须作为转换显示在系统目录
pg_cast 中。)
示例
要用函数 int4(text) 创建一个从
text 类型到
int4 类型的转换:
CREATE CAST (text AS int4) WITH FUNCTION int4(text);
(这个转换已经在系统中预定义。)
兼容性
CREATE CAST 命令符合
SQL99,只是
SQL99 没有为二进制兼容类型作规定。AS IMPLICIT 也是一种
PostgreSQL 扩展。