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

news/2024/7/9 22:18:33 标签: postgresql, 数据库

一、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)

http://www.niftyadmin.cn/n/1692685.html

相关文章

Java学习笔记 14、反射与JDK动态代理

文章目录前言一、认识反射二、认识Class类Class类获取Class实例的四种方式哪些类型可以是class对象?三、反射的方法使用获取构造器、类属性及方法如何看待反射与封装性两个技术?四、类的加载与ClassLoader理解类的加载过程(含例子)ClassLoader理解(各个类…

一个APP如何接入多个原生微信支付

背景 最近公司有一个需求,为了实现财务对账方便,想在原生APP里实现多个微信收款账户。理论上原生APP微信支付是不支持这种方式。IOS端实现方式就不介绍了,网上一堆,下面重点给大家介绍一下Android端的实现方法。 实现技术点 每个公…

Spring Boot 配置文件加载相关

为什么80%的码农都做不了架构师?>>> application.properties加载顺序 当前目录下的/config子目录, 当前目录。 一个classpath下的/config包 classpath根路径(root) 这个列表是按优先级排序的(列表中位置高…

C语言指针函数和函数指针的区别

指针函数&#xff08;本质是一个函数&#xff09;&#xff1a; int * GetDate(int wk,int dy);main(){int wk,dy;do{printf(Enter week(1-5)day(1-7)\n);scanf(%d%d,&wk,&dy);}while(wk<1||wk>5||dy<1||dy>7);printf(%d\n,*GetDate(wk,dy));}int * GetDate…

英伟达宣布推出首款面向边缘设备的人工智能平台

英伟达公司周一早些时候推出了新的英伟达EGX平台&#xff0c;将人工智能引入网络边缘&#xff0c;该平台能够实时感知、理解和处理数据&#xff0c;而无需首先将数据发送到云端或数据中心。将人工智能应用于智能手机、传感器和工厂机器等边缘设备是该技术不断发展的下一个阶段。…

数据库表的命名规范

数据库表的命名规范 1&#xff0e;表名一般以【模块名称_详细表名】来实现&#xff0c;同一个模块的前缀是一样的。(Oracle大写和小写敏感。在&#xff33;&#xff31;&#xff2c;中能够不用"_",由于能够用大写和小写一起的写法。 这也是能够的) 2&#xff0e;表名…

FLAG-尽力去做的最后半个学期+暑假

半期考核终于结束了 虽然是苟过去了 但是我自己心里还是很清楚自己的水平有多菜的 没有花太多时间学习技术 准备考试和运动会占用了挺多时间的 好不容易有些时间又因为没控制住自己 一贪玩就没了 fs说的很多挺重要的知识点都没怎么认真去学 平时作业也水的一批 不管怎么样过去的…

学习关于磁盘阵列raid系统基础

一.什么是RAIDRAID:Redundant Arrays of Inexpensive&#xff08;Independent&#xff09; Disks1988年由加利福尼亚大学伯克利分校&#xff08;University of CaliforniaBerkeley&#xff09; “A Case for Redundant Arrays of Inexpensive Disks”多个磁盘合成一个“阵列”来…