【问题标题】:Convert a bytea into a binary string将bytea转换为二进制字符串
【发布时间】:2019-09-24 05:07:13
【问题描述】:

我需要解码一个 base64 字符串并获取一大块二进制文件。

Postgres 中是否有一个 SQL 函数可以简单地将 bytea 转换为二进制字符串表示形式?
(如 “00010001010101010”。)

【问题讨论】:

    标签: postgresql binary-data bytea


    【解决方案1】:

    demo:db<>fiddle

    您可以将以下代码放入函数中:

    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
    

    我在小提琴中演示了查询的开发。

    1. WITH 子句封装了 bytea 值,以便在后续代码中重复使用
    2. length() 计算bytea 值的二进制长度
    3. generate_series() 创建一个从 0length - 1 的列表(在我的示例中为 0 - 3
    4. get_byte() 第二次获取bytea 值并给出位置gs 的字节(之前计算的值0-3)。这给出了字节的integer 表示。之后,转换为 bit(8) 类型将此函数的结果转换为其二进制表示形式(1 字节 = 8 位)
    5. 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
    

    demo:db<>fiddle

    【讨论】:

      【解决方案2】:

      如果您的 Postgres 安装使用默认设置 bytea_output = 'hex' 运行,则有一个非常简单的 hack:

      SELECT right(bytea_col::text, -1)::varbit;
      

      例子:

      SELECT right((bytea '\xDEADBEEF')::text, -1)::varbit;
      

      结果:

      '11011110101011011011111011101111'
      

      right(text, -1) 只是从文本表示中删除前导反斜杠的最便宜的方法。

      varbit(标准 SQL 名称 bit varying)用于任意长度的位串。将结果投射到textvarchar(如果你愿意)。

      相关,有解释:

      【讨论】:

        猜你喜欢
        • 2021-02-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-02
        • 2019-08-23
        • 1970-01-01
        相关资源
        最近更新 更多