PostgreSQL被除数为0处理方法

本文探讨了在Oracle和PostgreSQL中遇到除数为零时的错误处理方式,并提供了两种在PostgreSQL中优雅处理除零错误的方法,即使用CASE语句和自定义函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

0不能作为被除数这是数学中的常识,当在数据库中除以0时,应该如何处理呢?
在oracle和pg中是不允许被除数为0的。

oracle:

SQL> select 1/0 from dual;
select 1/0 from dual
        *
ERROR at line 1:
ORA-01476: divisor is equal to zero

PostgreSQL:

bill@bill=>\set VERBOSITY verbose 
bill@bill=>select 1/0;             
ERROR:  22012: division by zero
LOCATION:  int4div, int.c:824

我们可以在pg的代码中看到该报错的解释:

 813 Datum
 814 int4div(PG_FUNCTION_ARGS)
 815 {
 816         int32           arg1 = PG_GETARG_INT32(0);
 817         int32           arg2 = PG_GETARG_INT32(1);
 818         int32           result;
 819 
 820         if (arg2 == 0)
 821         {
 822                 ereport(ERROR,
 823                                 (errcode(ERRCODE_DIVISION_BY_ZERO),
 824                                  errmsg("division by zero")));
 825                 /* ensure compiler realizes we mustn't reach the division (gcc bug) */
 826                 PG_RETURN_NULL();
 827         }

但是,如果业务要求当被除数=0时,像mysql中一样返回空,而不是报错,在pg中该如何实现呢?
mysql:

mysql> select 1/0;
+------+
| 1/0  |
+------+
| NULL |
+------+
1 row in set, 1 warning (0.03 sec)

pg中对应的处理方法:

–方法一:
使用case语法

bill@bill=>select case when c2=0 then null else c1/c2 end from t2;
 case 
------
     
    2
    1
(3 rows)

–方法二:
自定义操作符

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

bill@bill=>create operator // (procedure=div_zero, leftarg=numeric, rightarg=numeric);  
CREATE OPERATOR

bill@bill=>select 1//0; 
 ?column? 
----------
         
(1 row)
### PostgreSQL中的除法运算 在PostgreSQL中,执行除法操作的方式取决于所使用的数据类型以及期望的结果精度。对于简单的整数除法,默认情况下会截断到最接近的整数值[^1]。 例如,在命令`select 2/4;`中,由于两个操作数都是整数,因此结果也是整数形式给出,即0。这是因为任何小于1的小数值都会被舍弃[^2]。 为了获得更精确的结果,可以将至少一个操作数转换为浮点数(`float8`)或高精度数字(`numeric`)类型: - 使用浮点数进行除法:`select 1/2.0;` 或者 `select 1/2::float8;` 将得到预期的小数结果0.5。 - 利用`numeric`类型可以获得更高的精度并保留更多的有效位数:`select 1/2::numeric;` 结果显示为带有多个零作为尾随数字的形式,如0.50000000000000000000。 为了避免不希望出现的情况——比如当分子比分母小时返回0,或是仅获取商的整数部分而丢失小数部分的信息,建议总是采用上述提到的方法之一来确保能够取得完整的算术结果[^3]。 另外值得注意的是处理可能出现的分母为零错误情况下的做法。通过SQL CASE表达式可以在检测到这种情况时提供替代输出而不是抛出异常;具体来说就是利用如下模式:`case when b = 0 then null else ROUND((a/b::NUMERIC),2)) end` 来安全地完成除法运算,并且还可以控制最终结果显示的有效位数[^4]。 ```sql SELECT CASE WHEN denominator = 0 THEN NULL ELSE CAST(numerator AS NUMERIC)/denominator END as result; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值