我有一个Postgres bytea
值,我想将其存储为decimal
类型(或交替作为带十进制数字的字符串)。它太长,不能存储为bigint
,但医生说decimal
值可以有多达131072位,这是足够大的。这是我需要处理的长度(150-300十六进制数字):
c30d040703020095dbb3d3746d096dd23b01c59bcbc7a4320f571511f61f3ea3def0e55404204a274500224927421bd5a8344a56316b909ef3af276b585622f1c9b7ca13563ee6fe88f4ddbe
问题是没有一个类似的问题能处理那么大的数字。有人有解决办法吗? 我的看法:
CREATE OR REPLACE FUNCTION parse_hex(s text) RETURNS numeric AS $$
DECLARE
len integer;
result bigint;
BEGIN
SELECT length(s) INTO len;
IF len <= 15 THEN
EXECUTE 'SELECT x''' || s || '''::bigint' INTO result;
RETURN result::numeric;
ELSE
RETURN parse_hex(left(s, (len+1)/2)) * (16::numeric)^(len/2) +
parse_hex(right(s, len/2));
RETURN 0;
END IF;
END;
$$ LANGUAGE plpgsql IMMUTABLE STRICT;
它使用二进制分割,即它将输入分成两半,并通过递归调用自身进行转换,然后将这两部分组合在一起。
编辑:我只是运行一个简单的基准测试,将上述函数与Abelisto链接的函数进行比较:
$ EXPLAIN ANALYZE SELECT parse_hex(n||'c30d040703020095dbb3d3746d096dd23b01c59bcbc7a4320f571511f61f3ea3def0e55404204a274500224927421bd5a8344a56316b909ef3af276b585622f1c9b7ca13563ee6fe88f4ddbe') FROM generate_series(1,1000) s(n);
Execution time: 640.031 ms
而对于hex2dec
,我得到
Execution time: 2354.616 ms
所以我的函数更快(对于这种大小的输入),我不知道它是否主要是因为二进制分割的渐近复杂性或它一次处理15个十六进制数字(而不是1)的事实。