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

简介:

标签

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数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
12月前
|
SQL 自然语言处理 关系型数据库
构建AI智能体:二十九、Text2SQL:告别繁琐SQL!用大模型自助生成数据报表
Text2SQL技术通过自然语言处理将用户查询转换为SQL语句,解决企业数据查询效率低下的痛点。该技术包含语义理解、模式对齐、SQL生成和优化等核心处理过程,核心组件包括自然语言理解模块、Schema管理模块和SQL生成模块。文章介绍了闭源和开源模型的选择策略,并提供了基于Function Calling的Text2SQL实现示例,展示如何安全高效地将自然语言转换为数据库查询。
4576 4
|
8月前
|
消息中间件 JavaScript 前端开发
详解事件循环与浏览器渲染机制
摘要:浏览器采用多进程架构,渲染主线程通过事件循环机制处理HTML解析、样式计算、布局等任务。异步机制避免主线程阻塞,任务按优先级在微队列、交互队列等不同队列中调度。JS执行会阻碍渲染,因其与渲染任务共享主线程。渲染流程包含解析、样式计算、布局、分层等阶段,最终由合成线程和GPU完成绘制。transform效率高因其仅影响合成阶段,不涉及主线程。reflow是布局重计算,repaint是绘制指令更新,两者均影响性能。
|
6月前
|
JSON 关系型数据库 MySQL
MySQL 8.0这几个功能太实用了!5分钟帮你省下70%的代码量
MySQL 8.0重磅升级,实操利器全面登场:CTE简化嵌套与递归查询,JSON_TABLE直解析JSON为表,窗口函数赋能高效分析,不可见索引提供删除“后悔药”,强化密码策略保障企业安全——性能、安全、开发效率三重跃升。
|
8月前
|
SQL 机器学习/深度学习 人工智能
从 NL2SQL 到本体论智能问数:为什么复杂企业数据问答需要新的方法
当“大模型+数据问答”成智能化入口,真正难点不在NL2SQL,而在理解业务对象、关系、口径与动作。本文剖析传统方法的天花板,提出以本体论构建业务语义层——将问数从“查表工具”升维为“决策基础设施”,揭示UINO等厂商通过ABC(Acquire-Build-Compute)范式,推动智能问数迈向可持续演进的语义底座。
|
9月前
|
SQL 安全 算法
Python 3.14 正式发布:七大重磅新特性详解
Python 3.14(2025.10发布)重磅升级:新增安全模板字符串(t-strings)、远程进程调试(pdb -p)、Zstandard标准压缩、注解默认延迟求值、智能语法纠错、统一compression命名空间及asyncio任务可视化工具,全面提升安全性、开发效率与运行性能。(239字)
977 0
|
10月前
|
移动开发 运维 Unix
Linux shutdown命令详解(小白也能看懂的完整教程)
本文详解Linux shutdown命令的使用方法,涵盖关机、重启、定时操作及单用户模式进入等实用技巧,适合新手快速掌握系统管理核心命令,提升运维能力。
|
自然语言处理 算法 Java
地址描述转换为坐标点不使用API,有什么转换的方法?
地址描述转换为坐标点不使用API,有什么转换的方法?
1092 64
|
Ubuntu 网络协议 应用服务中间件
在 Ubuntu 上安装 Nginx
在 Ubuntu 上安装和配置 Nginx 非常简单。首先更新系统包,然后通过 `apt` 安装 Nginx,检查服务状态并配置防火墙规则。访问服务器 IP 测试是否成功显示默认页面。还可管理服务、创建虚拟主机及排查常见问题,适合新手快速上手部署高性能 Web 服务。
1746 0
|
消息中间件 Linux
Linux IPC(进程间通信)管理:深入解析ipcs和ipcrm命令的用法与示例
在Linux操作系统中,进程间通信(IPC)是实现进程之间数据传递和同步的关键机制。Linux提供了多种IPC方式,如消息队列、信号量和共享内存等。为了优化系统性能与稳定性,及时管理和清理IPC资源非常重要。本文将深入介绍ipcs和ipcrm命令的使用方法,并给出丰富的示例,以帮助读者更好地理解IPC资源管理的实践技巧。
2019 1
|
SQL 自然语言处理 关系型数据库
在 Postgres 中使用 Concat
【8月更文挑战第11天】
1818 1