我有一个类型为 bytea 的数据库列。它包含转换为字节数组的浮点数(每个浮点数 4 个字节),编码为 Escape。我可以使用 substring 函数检索相应的 bytea 字符串。
我的问题是如何将 bytea 字符串转换为在 SQL 函数中浮动。早些时候我在 C# 端转换为浮动。我使用 dataReader.getByte 方法来检索字节,然后使用 BitConverter.ToSingle (.Net build in class) 方法转换为浮点数。
现在我不能使用中间组件作为 Npqsql 驱动程序。我希望 SQL 在从 3rd 方应用程序执行查询时直接将 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);
Run Code Online (Sandbox Code Playgroud)
然后通过考虑小端或大端得到二进制值
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;
Run Code Online (Sandbox Code Playgroud)
现在检查特殊情况:
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;
Run Code Online (Sandbox Code Playgroud)
如果它不属于任何特殊情况,只需将其转换如下:
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;
Run Code Online (Sandbox Code Playgroud)