【PostgreSQL-16新特性之类型转换测试功能】

一、PostgreSQL里的类型转换

在PostgreSQL里,“::” 符号其实是一个强制类型转换符,作用等同于CAST。
在很多情况下,我们需要将一种数据类型的值转换为另一种数据类型。那么我们就可以使用它来进行转换。

"::"的语法格式为:

expression::type

举个例子为:

postgres=# select '100'::integer,'100'::varchar;
 int4 | varchar 
------+---------
  100 | 100
(1 row)

CAST的语法格式为:

CAST ( expression AS target_type );

举个例子为:

postgres=# select CAST('100' as integer),CAST('100' as varchar);
 int4 | varchar 
------+---------
  100 | 100
(1 row)

除此之外类型转换可以使用一些to_开头的格式化函数进行转换,例如to_char,把数字转换成字符串等等。

postgres=# select to_char(125.8,'999D99MMM');
  to_char   
------------
  125.80MMM
(1 row)

二、类型转换失败会中断事务

但是在使用中,我们可能会遇到这样的问题,在PostgreSQL16版本之前,如果转换失败,则之前执行转换的失败的事务则会中断。

15.1 版本测试如下

postgres=# select version();
                                                       version                                                       
---------------------------------------------------------------------------------------------------------------------
 PostgreSQL 15.1 on aarch64-apple-darwin22.1.0, compiled by Apple clang version 14.0.0 (clang-1400.0.29.202), 64-bit
(1 row)

postgres=# select 'Abcd'::integer;
ERROR:  invalid input syntax for type integer: "Abcd"
LINE 1: select 'Abcd'::integer;
               ^
postgres=# 
postgres=# begin;
BEGIN
postgres=*# select now();
              now              
-------------------------------
 2023-07-04 12:01:45.204112+08
(1 row)

postgres=*#  select 'Abcd'::integer;
ERROR:  invalid input syntax for type integer: "Abcd"
LINE 1: select 'Abcd'::integer;
               ^
postgres=!#  select now();
ERROR:  current transaction is aborted, commands ignored until end of transaction block
postgres=!# end;
ROLLBACK

或者是使用CAST的时候发生转换失败,也会中断事务

postgres=# begin;
BEGIN
postgres=*# select CAST('100' as integer),CAST('100' as varchar);
 int4 | varchar 
------+---------
  100 | 100
(1 row)

postgres=*# select CAST('asd' as integer),CAST('100' as varchar);
ERROR:  invalid input syntax for type integer: "asd"
LINE 1: select CAST('asd' as integer),CAST('100' as varchar);
                    ^
postgres=!# select now();
ERROR:  current transaction is aborted, commands ignored until end of transaction block
postgres=!# end;
ROLLBACK

三、PostgreSQL16版本新增类型转换测试函数

PostgreSQL-16版本新增两个相关函数,pg_input_is_valid()和pg_input_error_message()。

postgres=# \df *input*
                                                                         List of functions
   Schema   |        Name         | Result data type |                                          Argument data types                                          | Type 
------------+---------------------+------------------+-------------------------------------------------------------------------------------------------------+------
 pg_catalog | pg_input_error_info | record           | value text, type_name text, OUT message text, OUT detail text, OUT hint text, OUT sql_error_code text | func
 pg_catalog | pg_input_is_valid   | boolean          | text, text                                                                                            | func
(2 rows)

pg_input_is_valid():测试转换是否成功或失败
pg_input_error_message():如果转换失败,可以查看错误信息

当我们在事务里进行想进行类型转换的时候,可以先用pg_input_is_valid()去测试是否可以正常转换,如果可以转换,函数返回t,再继续进行,如果函数返回结果为f,则不进行此转换,则不会因类型转换失败导致事务中断。

postgres=# select pg_input_is_valid('100','integer');
 pg_input_is_valid 
-------------------
 t
(1 row)

postgres=# select 100::integer;
 int4 
------
  100
(1 row)

postgres=# select pg_input_is_valid('Abcd','integer');
 pg_input_is_valid 
-------------------
 f
(1 row)

postgres=# select 'Abcd'::integer;
ERROR:  invalid input syntax for type integer: "Abcd"
LINE 1: select 'Abcd'::integer;
               ^

在发现转换失败的时候使用 pg_input_error_message()这个函数,将向我们提供错误消息。例如对上述的这个转换,我们不需要实际执行该转换,就可以通过函数,获取到转换的错误信息。这也避免了类型转换失败导致事务中断。

postgres=# select pg_input_error_info('Abcd','integer');
                     pg_input_error_info                     
-------------------------------------------------------------
 ("invalid input syntax for type integer: ""Abcd""",,,22P02)
(1 row)

你可能感兴趣的:(PostgreSQL,postgresql,数据库)