如何在博士后中完成溢出数学? 给定以下示例函数: 创建或替换函数add\u max\u值(\u x BIGINT) 返回BIGINT 语言sql 作为$$ 选择9223372036854775807+x; $$; 如果使用任何正值调用此函数,将返回以下错误: 选择添加最大值(1);--如果数学包装,预计为-9223372036854775808 --SQL错误[22003]:错误:bigint超出范围 如何在Postgres中进行溢出整数数学换行? 请注意: 我希望在数据库中执行此操作,而不是在应用程序中 我不希望它升级为任意精度的整数(NUMERIC) 虽然这个例子只做加法,但实际上我对其他操作也感兴趣
作为一个SQL函数,没有办法。SQL函数无法处理异常。但是如何在博士后中完成溢出数学? 给定以下示例函数: 创建或替换函数add\u max\u值(\u x BIGINT) 返回BIGINT 语言sql 作为$$ 选择9223372036854775807+x; $$; 如果使用任何正值调用此函数,将返回以下错误: 选择添加最大值(1);--如果数学包装,预计为-9223372036854775808 --SQL错误[22003]:错误:bigint超出范围 如何在Postgres中进行溢出整数数学换行? 请注意: 我希望在数据库中执行此操作,而不是在应用程序中 我不希望它升级为任意精度的整数(NUMERIC) 虽然这个例子只做加法,但实际上我对其他操作也感兴趣,sql,postgresql,plpgsql,Sql,Postgresql,Plpgsql,作为一个SQL函数,没有办法。SQL函数无法处理异常。但是plpgsql函数可以: CREATE OR REPLACE FUNCTION add_max_value(_x BIGINT) RETURNS BIGINT LANGUAGE plpgsql AS $$ declare bigx bigint; begin bigx = 9223372036854775807 + _x; return big
plpgsql
函数可以:
CREATE OR REPLACE FUNCTION add_max_value(_x BIGINT)
RETURNS BIGINT
LANGUAGE plpgsql
AS $$
declare
bigx bigint;
begin
bigx = 9223372036854775807 + _x;
return bigx;
exception
when sqlstate '22003' then
return (9223372036854775807::numeric + _x - 2^64)::bigint;
end;
$$;
这是我写过的最浪费SQL中的前五位:
create or replace function add_max_value(_x bigint)
returns bigint
language sql
as $$
with recursive inputs as (
select s.rn, r.a::int, s.b::int, (r.a::int + s.b::int) % 2 as sumbit,
(r.a::bit & s.b::bit)::int as carry
from regexp_split_to_table((9223372036854775807::bit(64))::text, '') with ordinality as r(a, rn)
join regexp_split_to_table((_x::bit(64))::text, '') with ordinality as s(b, rn)
on s.rn = r.rn
), addition as (
select rn, sumbit, sumbit as s2, carry, carry as upcarry
from inputs
where rn = 64
union
select i.rn, i.sumbit, (i.sumbit + a.upcarry) % 2, i.carry,
(i.carry::bit | a.upcarry::bit)::int
from addition a
join inputs i on i.rn = a.rn - 1
)
select (string_agg(s2::text, '' order by rn)::bit(64))::bigint
from addition
$$;
该函数是否真的会在负输入时引发错误?@a_horse_与_no_name在第二个代码块中出现预期结果。重申一下,许多主流语言(C、Java)都提供相同的包装行为;正整数是示例中的问题。问题更新。除了在PL/pgSQL中使用中间
numeric
变量和手动“包装”之外,我看不到任何其他方法。你会比我更清楚。但是,是的,你也可以只“返回1”。没问题。具体情况无关紧要,这是处理异常的概念,尤其是处理特定的异常。首先将加法的结果分配给数值
变量,然后检查它是否大于9223372036854775807
会更有效吗?异常处理是相当昂贵的是的,对于故意导致异常的人为示例,但我认为对于算术溢出的一般情况并非如此。我不认为OP的问题与具体的例子有关,而是与一般情况有关。如果问题是针对特定示例的,那么更有效的方法是直接使用语句“select(9223372036854775807::numeric+\ux-2^64)::bigint;”的SQL函数重置值