大佬教程收集整理的这篇文章主要介绍了在PostgreSQL中将bytea转换为双精度,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
好的,我找到了答案。在postgresql中,您可以使用Python编写函数。为了启用Python,您必须安装Postgresql安装所需的特定版本的Python,并将其在PATH环境变量中可用。您可以通过查看安装说明找到postgresql安装所需的Python版本。我目前在windows上使用PostgreSQL 9.6.5,它要求使用Python 3.3。我最初尝试了最新的Python 3.6,但无法正常工作。我选择了适用于windows的最新Python 3.3,即3.3.5。
安装Python之后,您可以CREATE EXTENSION
plpython3u;
按照https://www.POSTGResql.org/docs/current/static/plpython.html所述在数据库上执行,从而在postgresql中启用它。从那里,您可以使用Python主体编写任何函数。
对于我的具体情况,从转换bytea
到double precision[]
背,我写了下面的功能:
create functION bytea_to_double_array(b bytea)
RETURNS double precision[]
LANGUAGE 'plpython3u'
AS $BODY$
if 'struct' in GD:
struct = GD['struct']
else:
import struct
GD['struct'] = struct
return struct.unpack('<' + str(int(len(b) / 8)) + 'd', b)
$BODY$;
create functION double_array_to_bytea(dblarray double precision[])
RETURNS bytea
LANGUAGE 'plpython3u'
AS $BODY$
if 'struct' in GD:
struct = GD['struct']
else:
import struct
GD['struct'] = struct
# dblarray here is really a List.
# POSTGResql passes sql arrays as Python Lists
return struct.pack('<' + str(int(len(dblarray))) + 'd', *dblarray)
$BODY$;
在我的情况下,所有双打都存储在little
endian中,因此我使用<
。我还struct
按照的描述,将模块的导入缓存在全局字典中。我使用GD而不是SD,因为我希望导入可以在我可能编写的其他函数中使用。有关GD和SD的信息,请参见https://www.POSTGResql.org/docs/current/static/plpython-
sharing.HTML。
要了解它的作用,请知道我数据库中的blob以小字节序存储,
SELECT bytea_to_double_array(decode('efbeaddeefbeadde', 'hex')), encode(double_array_to_bytea(arraY[-1.1885959257070704E148]), 'hex');
我得到的答案是
bytea_to_double_array | encode
double precision[] | text
-------------------------+------------------
{-1.18859592570707e+148} | efbeaddeefbeadde
这里'efbeaddeefbeadde'
是'deadbeefdeadbeef'
在小尾数。
我有一个数据库,其中的一个表存储bytea
从另一个系统收集的各种通用数据的Blob()。该bytea
字段可以包含任何内容。为了知道如何解释数据,该表还具有一个格式字段。我写了一个Java应用程序读取bytea
从数据库的字段byte[]
,然后我可以很容易地将其转换为double[]
或int[]
或任何格式字段表示,通过ByteBuffer
与各种视图(DoubleBuffer
,IntBuffer
,等)。
现在,我需要在触发器函数中对数据库本身上的数据进行一些操作,以保持与另一个表的完整性。我可以找到几乎可以想象到的任何数据类型的转换,但是我找不到从bytea
(甚至bit
到)往返的任何数据double
precision
。bytea
可以将A分解,转换为位,然后转换为int
or bigint
,但不能转换为a double
precision
。例如,x'deadbeefdeadbeef'::bit(64)::bigint
将毫无问题地转换为-2401053088876216593
,而是x'deadbeefdeadbeef'::bit(64)::double
precision
失败,并显示“错误:无法将类型位转换为双精度”,而不给出IEEE 754的答案-1.1885959257070704E148
。
我找到了这个答案它基本上实现了IEEE标准,可以将位转换为两倍,但是postgresql中确实没有基本的转换功能吗?另外,当我处理完数据并需要更新表时,我也需要倒退double
precision
,bytea
直到这个答案没有提供。
最好的解决方案是使用sqL命令使用IEEE754-1985标准将其转换为字节。
首先,需要检查IEEE754-1985标准定义的特殊情况。然后,如果不是特殊情况,只需遵循标准算法进行转换。示例代码如下。
bytea_value bytea,is_little_endian Boolean
然后将输入分为4个字节,如下所示:
byte_array[0]:= geT_Byte(bytea_value,0);
byte_arraY[1]:= geT_Byte(bytea_value,1);
byte_array[2]:= geT_Byte(bytea_value,2);
byte_arraY[3]:= geT_Byte(bytea_value,3);
然后通过考虑小端或大端获得二进制值
IF is_little_endian THEN
binary_value:= byte_array[0]::bit(8) || byte_arraY[1]::bit(8) || byte_array[2]::bit(8) || byte_arraY[3]::bit(8);
ELSE
binary_value:= byte_arraY[3]::bit(8) || byte_array[2]::bit(8) || byte_arraY[1]::bit(8) || byte_array[0]::bit(8);
END IF;
现在检查特殊情况:
IF binary_value = '00000000000000000000000000000000' OR binary_value = '10000000000000000000000000000000' THEN -- IEEE754-1985 Zero
return 0.0;
END IF;
sign := subString(binary_value from 1 for 1);
exponent := subString(binary_value from 2 for 8);
mantissa := subString(binary_value from 10 for 23);
IF exponent = '11111111' THEN
IF mantissa = '00000000000000000000000' THEN -- IEEE754-1985 negative and positive infinity
IF sign = '1' THEN
return '-Infinity';
ELSE
return 'Infinity';
END IF;
ELSE
return 'NaN'; -- IEEE754-1985 Not a number
END IF;
END IF;
如果它不属于任何特殊情况,则将其转换如下:
exp := exponent::int;
IF exp > 126 THEN
exp := exp - 127;
ELSE
exp:= -exp;
END IF;
WHILE mantissa_index < 24 LOOP
IF subString(mantissa from mantissa_index for 1) = '1' THEN
result := result + power(2,-(mantissa_indeX));
END IF;
mantissa_index = mantissa_index + 1;
END LOOP;
result := result * power(2,exp);
IF(sign = '1') THEN
result = -result;
END IF;
return result;
有任何想法吗?
以上是大佬教程为你收集整理的在PostgreSQL中将bytea转换为双精度全部内容,希望文章能够帮你解决在PostgreSQL中将bytea转换为双精度所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。