PostgreSQL 自定义自动类型转换(CAST) integer_to_text

PostgreSQL是一个强类型数据库,因此你输入的变量、常量是什么类型,是强绑定的,例如

在调用操作符时,需要通过操作符边上的数据类型,选择对应的操作符。

在调用函数时,需要根据输入的类型,选择对应的函数。

如果类型不匹配,就会报操作符不存在,或者函数不存在的错误。

  1. postgres=# select ‘1‘ + ‘1‘;

  2.  

    ERROR: operator is not unique: unknown + unknown

  3.  

    LINE 1: select ‘1‘ + ‘1‘;

  4.  

    ^

  5.  

    HINT: Could not choose a best candidate operator. You might need to add explicit type casts.

那么使用起来是不是很不方便呢?

PostgreSQL开放了类型转换的接口,同时也内置了很多的自动类型转换。来简化操作。

查看目前已有的类型转换:

  1. postgres=# \dC+

  2.  

    List of casts

  3.  

    Source type | Target type | Function | Implicit? | Description

  4.  

    -----------------------------+-----------------------------+--------------------+---------------+-------------

  5.  

    "char" | character | bpchar | in assignment |

  6.  

    "char" | character varying | text | in assignment |

  7.  

    "char" | integer | int4 | no |

  8.  

    "char" | text | text | yes |

  9.  

    abstime | date | date | in assignment |

  10.  

    abstime | integer | (binary coercible) | no |

  11.  

    abstime | time without time zone | time | in assignment |

  12.  

  13.  

    ................................

  14.  

  15.  

    timestamp without time zone | timestamp with time zone | timestamptz | yes |

  16.  

    timestamp without time zone | timestamp without time zone | timestamp | yes |

  17.  

    xml | character | (binary coercible) | in assignment |

  18.  

    xml | character varying | (binary coercible) | in assignment |

  19.  

    xml | text | (binary coercible) | in assignment |

  20.  

    (246 rows)

如果你发现有些类型转换没有内置,怎么办呢?我们可以自定义转换。

当然你也可以使用这种语法,对类型进行强制转换:

  1. CAST(x AS typename)

  2.  

  3.  

    or

  4.  

  5.  

    x::typename

如何自定义类型转换(CAST)

自定义CAST的语法如下:

  1. CREATE CAST (source_type AS target_type)

  2.  

    WITH FUNCTION function_name [ (argument_type [, ...]) ]

  3.  

    [ AS ASSIGNMENT | AS IMPLICIT ]

  4.  

  5.  

    CREATE CAST (source_type AS target_type)

  6.  

    WITHOUT FUNCTION

  7.  

    [ AS ASSIGNMENT | AS IMPLICIT ]

  8.  

  9.  

    CREATE CAST (source_type AS target_type)

  10.  

    WITH INOUT

  11.  

    [ AS ASSIGNMENT | AS IMPLICIT ]

解释:

1、WITH FUNCTION,表示转换需要用到什么函数。

2、WITHOUT FUNCTION,表示被转换的两个类型,在数据库的存储中一致,即物理存储一致。例如text和varchar的物理存储一致。不需要转换函数。

  1. Two types can be binary coercible,

  2.  

    which means that the conversion can be performed “for free” without invoking any function.

  3.  

  4.  

    This requires that corresponding values use the same internal representation.

  5.  

  6.  

    For instance, the types text and varchar are binary coercible both ways.

  7.  

  8.  

    Binary coercibility is not necessarily a symmetric relationship.

  9.  

  10.  

    For example, the cast from xml to text can be performed for free in the present implementation,

  11.  

    but the reverse direction requires a function that performs at least a syntax check.

  12.  

  13.  

    (Two types that are binary coercible both ways are also referred to as binary compatible.)

3、WITH INOUT,表示使用内置的IO函数进行转换。每一种类型,都有INPUT 和OUTPUT函数。使用这种方法,好处是不需要重新写转换函数。

除非有特殊需求,我们建议直接使用IO函数来进行转换。

  1. List of functions

  2.  

    Schema | Name | Result data type | Argument data types | Type

  3.  

    ------------+-----------------+------------------+---------------------+--------

  4.  

    pg_catalog | textin | text | cstring | normal

  5.  

    pg_catalog | textout | cstring | text | normal

  6.  

    pg_catalog | date_in | date | cstring | normal

  7.  

    pg_catalog | date_out | cstring | date | normal

  1. You can define a cast as an I/O conversion cast by using the WITH INOUT syntax.

  2.  

  3.  

    An I/O conversion cast is performed by invoking the output function of the source data type,

  4.  

    and passing the resulting string to the input function of the target data type.

  5.  

  6.  

    In many common cases, this feature avoids the need to write a separate cast function for conversion.

  7.  

  8.  

    An I/O conversion cast acts the same as a regular function-based cast; only the implementation is different.

4、AS ASSIGNMENT,表示在赋值时,自动对类型进行转换。例如字段类型为TEXT,输入的类型为INT,那么可以创建一个 cast(int as text) as ASSIGNMENT。

  1. If the cast is marked AS ASSIGNMENT then it can be invoked implicitly when assigning a value to a column of the target data type.

  2.  

  3.  

    For example, supposing that foo.f1 is a column of type text, then:

  4.  

  5.  

    INSERT INTO foo (f1) VALUES (42);

  6.  

  7.  

    will be allowed if the cast from type integer to type text is marked AS ASSIGNMENT,

  8.  

    otherwise not.

  9.  

  10.  

    (We generally use the term assignment cast to describe this kind of cast.)

5、AS IMPLICIT,表示在表达式中,或者在赋值操作中,都对类型进行自动转换。(包含了AS ASSIGNMENT,它只对赋值进行转换)

  1. If the cast is marked AS IMPLICIT then it can be invoked implicitly in any context,

  2.  

    whether assignment or internally in an expression.

  3.  

  4.  

    (We generally use the term implicit cast to describe this kind of cast.)

  5.  

  6.  

    For example, consider this query:

  7.  

  8.  

    SELECT 2 + 4.0;

  9.  

  10.  

    The parser initially marks the constants as being of type integer and numeric respectively.

  11.  

  12.  

    There is no integer + numeric operator in the system catalogs, but there is a numeric + numeric operator.

  13.  

  14.  

    The query will therefore succeed if a cast from integer to numeric is available and is marked AS IMPLICIT —

  15.  

    which in fact it is.

  16.  

  17.  

    The parser will apply the implicit cast and resolve the query as if it had been written

  18.  

  19.  

    SELECT CAST ( 2 AS numeric ) + 4.0;

6、注意,AS IMPLICIT需要谨慎使用,为什么呢?因为操作符会涉及到多个算子,如果有多个转换,目前数据库并不知道应该选择哪个?

  1. Now, the catalogs also provide a cast from numeric to integer.

  2.  

  3.  

    If that cast were marked AS IMPLICIT — (which it is not — )

  4.  

  5.  

    then the parser would be faced with choosing between the above interpretation and

  6.  

    the alternative of casting the numeric constant to integer and applying the integer + integer operator.

  7.  

  8.  

    Lacking any knowledge of which choice to prefer, it would give up and declare the query ambiguous.

  9.  

  10.  

    The fact that only one of the two casts is implicit is the way in which we teach the parser to prefer resolution of

  11.  

    a mixed numeric-and-integer expression as numeric;

  12.  

  13.  

    there is no built-in knowledge about that.

因此,建议谨慎使用AS IMPLICIT。建议使用AS IMPLICIT的CAST应该是非失真转换转换,例如从INT转换为TEXT,或者int转换为numeric。

而失真转换,不建议使用as implicit,例如numeric转换为int。

  1. It is wise to be conservative about marking casts as implicit.

  2.  

  3.  

    An overabundance of implicit casting paths can cause PostgreSQL to choose surprising interpretations of commands,

  4.  

    or to be unable to resolve commands at all because there are multiple possible interpretations.

  5.  

  6.  

    A good rule of thumb is to make a cast implicitly invokable only for information-preserving

  7.  

    transformations between types in the same general type category.

  8.  

  9.  

    For example, the cast from int2 to int4 can reasonably be implicit,

  10.  

    but the cast from float8 to int4 should probably be assignment-only.

  11.  

  12.  

    Cross-type-category casts, such as text to int4, are best made explicit-only.

注意事项 + 例子

不能嵌套转换。例子

1、将text转换为date

错误方法

  1. create or replace function text_to_date(text) returns date as $$

  2.  

    select cast($1 as date);

  3.  

    $$ language sql strict;

  4.  

  5.  

    create cast (text as date) with function text_to_date(text) as implicit;

嵌套转换后出现死循环

  1. postgres=# select text ‘2017-01-01‘ + 1;

  2.  

    ERROR: stack depth limit exceeded

  3.  

    HINT: Increase the configuration parameter "max_stack_depth" (currently 2048kB), after ensuring the platform‘s stack depth limit is adequate.

  4.  

    CONTEXT: SQL function "text_to_date" during startup

  5.  

    SQL function "text_to_date" statement 1

  6.  

    SQL function "text_to_date" statement 1

  7.  

    SQL function "text_to_date" statement 1

  8.  

    ......

正确方法

  1. create or replace function text_to_date(text) returns date as $$

  2.  

    select to_date($1,‘yyyy-mm-dd‘);

  3.  

    $$ language sql strict;

  4.  

  5.  

    create cast (text as date) with function text_to_date(text) as implicit;

  1. postgres=# select text ‘2017-01-01‘ + 1;

  2.  

    ?column?

  3.  

    ------------

  4.  

    2017-01-02

  5.  

    (1 row)

我们还可以直接使用IO函数来转换:

  1. postgres=# create cast (text as date) with inout as implicit;

  2.  

    CREATE CAST

  3.  

  4.  

    postgres=# select text ‘2017-01-01‘ + 1;

  5.  

    ?column?

  6.  

    ------------

  7.  

    2017-01-02

  8.  

原文地址:https://www.cnblogs.com/caicaizi/p/12642774.html

时间: 2024-10-13 07:55:34

PostgreSQL 自定义自动类型转换(CAST) integer_to_text的相关文章

Java自动类型转换和强制类型转换

1.容量小的数据类型可以自动转成容量大的数据类型(注:容量大指的是数据类型表征的范围大.) 2.数据自动类型转换: cast:转型 long型可以自动转换成float但是可能丢失精度. int型转换为char型需要强制转型. 但是char型转成int是不需要强制转换. 3.表达式中类型提升问题.

自动类型转换之构造函数

在c/c++中,如果编译器看到一个表达式或函数调用使用了一个不适合的类型,它经常会执行一个自动类型转换,从现在的类型到所有要求的类型.在内置类型中我们经常看到例如: char c; int i=c; 上述语句就执行了自动类型转换.但是上面只是内置类型的自动类型转换,在c++中,还支持用户自定义的自动类型转换.有两种方法可以实习,第一种方法就是特殊类型的构造函数,第二种就是重载的运算符. 首先介绍第一种,特殊的构造函数.如果定义一个构造函数,这个构造函数把另一个类型的对象或者引用当做它的单个参数,

C语言自动类型转换

自动转换遵循以下规则: 1) 若参与运算量的类型不同,则先转换成同一类型,然后进行运算. 2) 转换按数据长度增加的方向进行,以保证精度不降低.(eg:int型和long型运算时,先把int量转成long型后再进行运算.) a.若两种类型的字节数不同,转换成字节数高的类型 b.若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型 3) 所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算. 4) char型和short型参

java的自动类型转换和强制类型转换

一.自动类型转换 在 Java 程序中,不同的基本数据类型的数据之间经常需要进行相互转换.例如: , 代码中 int 型变量 score1 可以直接为 double 型变量 score2 完成赋值操作,运行结果为: 82.0  这种转换称为自动类型转换. 当然自动类型转换是需要满足特定的条件的:目标类型大于元类型 二.强制类型转换 当程序中需要将 double 型变量的值赋给一个 int 型变量,该如何实现呢? 显然,这种转换是不会自动进行的!因为 int 型的存储范围比 double 型的小.

自动类型转换

说完了强制类型转换,再来看看自动类型转换,实际上自动类型转换是建立在强制类型转换的基础上,当预期某个位置应该是某类型(布尔.数值.字符串)的数据时,就会调用相应的强制类型转换函数,这个是自动进行的. *当JavaScript遇到预期为布尔值的地方(比如if语句的条件部分),就会将非布尔值的参数自动转换为布尔值.系统内部会自动调用Boolean函数. 因此除了以下六个值,其他都是自动转为true. undefined null -0 0或+0 NaN ''(空字符串) *当JavaScript遇到

功能:自动类型转换

#include<stdio.h> main() { float x,y; long m,n; x=3/2+8/3; y=3.0/2+8/3.0; m=1*2*3*4*5*6*7*8*9; n=1L*2*3*4*5*6*7*8*9; printf("x=%f,y=%f,m=%ld,n=%ld\n",x,y,m,n); } 功能:自动类型转换,布布扣,bubuko.com

第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all; Select 列 into 新表;字符串函数;日期函数

第17课-数据库开发及ado.net 聚合函数,模糊查询like,通配符.空值处理.order by排序.分组group by-having.类型转换-cast,Convert.union all;  Select 列 into 新表;字符串函数;日期函数 SQL聚合函数 MAX(最大值).MIN(最小值).AVG(平均值).SUM(和).COUNT(数量:记录的条数) 聚合函数对null不计算.如果一行数据都是null,count(*)包含对空值行.重复行的统计. --聚合函数演示 selec

PHP第五课 自动类型转换与流程控制

学习概要: 1.了解自动类型转换的有哪些 2.了解基本的流程控制语句 3.实例:实现日历表格的写法 自动类型转换 1)整型转字符串 echo $num."abc"; 2)字符串转整型 $str+3; 3)转布尔类型 为假情况 0 "" "0" false array() null 未定义 4)强制类型转换 (int)$str (float)$str (string)$str 5)常量 define("HOST","l

struts基于ognl的自动类型转换需要注意的地方

好吧,坎坷的过程我就不说了,直接上结论: 在struts2中使用基于ognl的自动类型转换时,Action中的对象属性必须同时添加get/set方法. 例如: 客户端表单: <s:form action="registPro"> <s:textfield name="user.id" label="id"/> <s:textfield name="user.name" label="用户