我需要解码base64字符串并获取二进制文件的一部分。
Postgres中是否有SQL函数可以将bytea
转换为二进制字符串表示形式?
(例如“ 00010001010101010” 。)
答案 0 :(得分:1)
您可以将以下代码放入函数中:
WITH byte AS ( -- 1
SELECT E'\\xDEADBEEF'::bytea as value
)
SELECT
string_agg( -- 5
get_byte(value, gs)::bit(8)::text -- 4
, ''
)
FROM
byte,
generate_series( -- 3
0,
length(value) - 1 -- 2
) gs
我在小提琴中演示了查询的发展。
WITH
子句封装了bytea
值,以便在进一步的代码中重复使用length()
计算bytea
值的二进制长度generate_series()
创建一个从0
到length - 1
(在我的示例中为0 - 3
)的列表get_byte()
第二次获取bytea
值,并给出位置gs
处的字节(先前的计算值0-3
)。这给出了字节的integer
表示形式。之后,将类型转换为bit(8)
会将此函数的结果转换为其二进制表示形式(1字节= 8位)string_agg()
最后将所有二进制字符串汇总为一个。 (采用其text
表示形式代替bit
类型,没有分隔符)一个函数可能看起来像这样:
CREATE OR REPLACE FUNCTION to_bit(value bytea) RETURNS SETOF text AS
$$
BEGIN
RETURN QUERY
SELECT
string_agg(get_byte(value, gs)::bit(8)::text, '')
FROM
generate_series(0, length(value) - 1) gs;
END;
$$ LANGUAGE plpgsql;
之后,您可以将其命名为:
SELECT to_bit(E'\\xDEADBEEF'::bytea)
您可以使用get_bit()
而不是get_byte()
进行尝试。这样可以确保::bit(8)
的使用安全,但是当然您需要将长度乘以因子8
。
生成的位字符串具有另一个位顺序,但也许更适合您的用例:
WITH byte AS (
SELECT E'\\xDEADBEEF'::bytea as value
)
SELECT
string_agg(get_bit(value, gs)::text, '')
FROM
byte,
generate_series(0, length(value) * 8 - 1) gs
答案 1 :(得分:1)
假设您的Postgres安装以bytea_output
的默认设置hex
运行,有一个非常简单的技巧:
SELECT right((bytea '\xDEADBEEF')::text, -1)::varbit
结果:
'11011110101011011011111011101111'
right(text, -1)
只是从文本表示中删除前导反斜杠的最便宜方法。
varbit
(或其在标准SQL中的正式名称:bit varying
)用于任意长度的位st。如果需要,将结果转换为text
或varchar
。
相关,并附有说明: