在PostgreSQL中将bytea表示为单个整数的最简单方法是什么?

Zol*_*tán 6 postgresql casting converter postgresql-9.2

我有一个bytea包含14个字节数据的列.14的最后3个字节包含数据的CRC码.我想将CRC提取为一个整数,以存储在新列中.

我该怎么做呢?

为了澄清,这是在Java中实现它的一种方法:

int crc = ((rawData[len - 3] & 0xff) << 16 |
            (rawData[len - 2] & 0xff) << 8 |
            (rawData[len - 1] & 0xff)) & 0xffffff;
Run Code Online (Sandbox Code Playgroud)

我希望找到一个没有位移的解决方案,即类似于接受4个字节并将它们转换为整数的方法.

Erw*_*ter 11

另一种方法是在hex表示中提取最后6个字符,x直接添加和直接转换:

db=# SELECT ('x' || right('\x00000000000001'::bytea::text, 6))::bit(24)::int;
 int4
------
    1
Run Code Online (Sandbox Code Playgroud)

..比get_byte()路线短一点,但也是PostgreSQL的一个未记录的功能.但是,我在这里引用Tom Lane:

这依赖于位型输入转换器的一些未记录的行为,但我认为没有理由期望会破坏.一个可能更大的问题是它需要PG> = 8.3,因为在此之前没有要进行比特转换的文本.

这个相关答案的细节:

这假定您的设置bytea_outputhex,这是自9.0版以来的默认设置.当然,您可以为会话测试/设置它:

SET bytea_output = 'hex';
Run Code Online (Sandbox Code Playgroud)

更多信息:

性能

我在一个有10k行的桌子上进行了测试(最好的10个).get_byte()在Postgres 9.1中实际上要快一点:

CREATE TEMP TABLE t (a bytea);
INSERT INTO t
SELECT (12345670000000 + generate_series(1,10000))::text::bytea;
Run Code Online (Sandbox Code Playgroud)

比特移位与乘法/加法一样快:

SELECT 
 ('x' || right(a::text, 6))::bit(24)::int                           -- 34.9 ms
,(get_byte(a, 11) << 16) + (get_byte(a, 12) << 8) + get_byte(a, 13) -- 27.0 ms
,(get_byte(a, 11) << 16) | (get_byte(a, 12) << 8) | get_byte(a, 13) -- 27.1 ms
, get_byte(a, 11) * 65536 + get_byte(a, 12) * 256 + get_byte(a, 13) -- 27.1 ms
FROM t
Run Code Online (Sandbox Code Playgroud)

  • @CraigRinger:有时力量的黑暗面太诱人了.:) (2认同)

Clo*_*eto 5

select get_byte(b, 11) * 65536 + get_byte(b, 12) * 256 + get_byte(b, 13)
from (values ('12345678901234'::bytea)) s(b);
 ?column? 
----------
  3289908
Run Code Online (Sandbox Code Playgroud)