PostgreSQL 在被除数=0时的小纯真和小倔强

本文涉及的产品
RDS AI 助手,专业版
PolarDB Agent Express,2核4GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介:

标签

PostgreSQL , 被除数=0 , UDF , 自定义操作符


背景

0不能作为被除数,小学就学过的知识。

对于数据库来说,设计严谨,遵循一些基本的原则也是很有必要的。

当在数据库中除以0时,应该如何处理呢?

PostgreSQL为例,它具有非常浓烈的学院派风格,你说它你能让你除以0吗?

显然不让,如下:

postgres=# select 1/0;
ERROR: 22012: division by zero
LOCATION: int4div, int.c:719

代码中,我们可以看到对应的报错

Datum  
int4div(PG_FUNCTION_ARGS)  
{  
        int32           arg1 = PG_GETARG_INT32(0);  
        int32           arg2 = PG_GETARG_INT32(1);  
        int32           result;  

        if (arg2 == 0)  
        {  
                ereport(ERROR,  
                                (errcode(ERRCODE_DIVISION_BY_ZERO),  
                                 errmsg("division by zero")));  
                /* ensure compiler realizes we mustn't reach the division (gcc bug) */  
                PG_RETURN_NULL();  
        }  

但是,如果业务要求当被除数=0时,返回空,而不是报错,(又或者返回其他值)应该怎么处理呢?

除以0时返回空如何处理?

方法1

SQL标准中,有case的语法,可以用来支持被除数=0时返回其他值。

写法举例

select case when c2=0 then null else c1/c2 end from tbl ....;  

方法2

自定义操作符

PostgreSQL允许用户自定义操作符,实现业务需求的逻辑

例子

create or replace function div_zero(numeric, numeric) returns numeric as $$                 
select case when $2 <> 0 then $1/$2 else null end ;                
$$ language sql strict immutable;  

postgres=# create operator // (procedure=div_zero, leftarg=numeric, rightarg=numeric);  
CREATE OPERATOR  
postgres=# select 1//0;  
 ?column?   
----------  

(1 row)  

postgres=# select 1//1.1;  
        ?column?          
------------------------  
 0.90909090909090909091  
(1 row)  

方法3

修改PG源码,新增一个GUC变量如enable_divs_zero,默认为off,则使用原有的处理方式。

当enable_divs_zero=on时,返回NULL.

例如对于INT类型,修改这个,其他类型修改对应的.c即可

Datum  
int4div(PG_FUNCTION_ARGS)  
{  
        int32           arg1 = PG_GETARG_INT32(0);  
        int32           arg2 = PG_GETARG_INT32(1);  
        int32           result;  

        if (arg2 == 0)  
        {  
                // 加GUC判断,如果enable_divs_zero=off, 报错, 否则返回NULL  
        ereport(ERROR,  
                                (errcode(ERRCODE_DIVISION_BY_ZERO),  
                                 errmsg("division by zero")));  

                /* ensure compiler realizes we mustn't reach the division (gcc bug) */  
                PG_RETURN_NULL();  
        }  

小结

PostgreSQL在很多方面都有一些学院派的小倔强,或者说趋于严谨的作风。

不过它很多开放的接口,所以,用户有什么特殊的需求,都是可以解决的。

相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
编解码 计算机视觉
使用ffmpeg将图片合成为视频(附完整参数介绍)
ffmpeg -f image2 -i %d.jpeg -vf scale=-1:480 output5.mp4 #-1表示比例缩放,也可-vf scale=640:-1固定宽度缩放高度
2327 0
|
Linux
Linux大文件查看利器:掌握Less命令的使用和技巧
Linux大文件查看利器:掌握Less命令的使用和技巧
2411 0
|
10月前
|
存储 监控 算法
基于跳表数据结构的企业局域网监控异常连接实时检测 C++ 算法研究
跳表(Skip List)是一种基于概率的数据结构,适用于企业局域网监控中海量连接记录的高效处理。其通过多层索引机制实现快速查找、插入和删除操作,时间复杂度为 $O(\log n)$,优于链表和平衡树。跳表在异常连接识别、黑名单管理和历史记录溯源等场景中表现出色,具备实现简单、支持范围查询等优势,是企业网络监控中动态数据管理的理想选择。
268 0
|
SQL 监控 关系型数据库
PostgreSQL普通表转换成分区表
如何使用pg_rewrite扩展将普遍表转换成分区表
|
SQL 自然语言处理 关系型数据库
在 Postgres 中使用 Concat
【8月更文挑战第11天】
1536 1
|
缓存 运维 监控
PostgreSQL运维技巧之vacuum调优
PostgreSQL运维技巧之vacuum调优
1730 3
|
双11 文件存储 前端开发
限量版阿里云手办,原来这么简单就拿到了(附详细攻略)
阿里云今年双11出了个“带云小宝回家”的活动,一共限量3000个手办,还挺有科技感,出个攻略,方便大家去薅羊毛。按照下面的步骤,一步一步操作就行。
2800 0
限量版阿里云手办,原来这么简单就拿到了(附详细攻略)
|
存储 关系型数据库 数据库
经验大分享:PostgreSQL学习之【用户权限管理】说明
经验大分享:PostgreSQL学习之【用户权限管理】说明
1636 1
|
存储 关系型数据库 数据库
PostgreSQL在进行除法时要注意
PostgreSQL在进行除法时要注意
393 0
|
消息中间件 Kafka 网络安全
Kafka. Broker not available
Kafka. Broker not available
605 0