我有一个包含14个字节数据的bytea列. 14的最后3个字节包含数据的CRC码.我想将CRC提取为一个整数,以存储在新列中.
我该怎么做呢?
int crc = ((rawData[len - 3] & 0xff) << 16 | (rawData[len - 2] & 0xff) << 8 | (rawData[len - 1] & 0xff)) & 0xffffff;
另一种方法是以十六进制表示形式提取最后6个字符,预先添加x并直接转换:
db=# SELECT ('x' || right('\x00000000000001'::bytea::text,6))::bit(24)::int; int4 ------ 1
..比get_byte()路由短一点,但也是Postgresql的一个未记录的功能.但是,我引用Tom Lane here:
This is relying on some undocumented behavior of the bit-type input
converter,but I see no reason to expect that would break. A possibly
bigger issue is that it requires PG >= 8.3 since there wasn’t a text
to bit cast before that.
这个相关答案的细节:
> Convert hex in text representation to decimal number
这假设您的bytea_output设置为十六进制,这是自9.0版以来的默认设置.当然,您可以为会话测试/设置它:
SET bytea_output = 'hex';
更多信息:
> PostgreSQL 9.X bytea representation in ‘hex’ or ‘escape’ for thumbnail images
我在一个有10k行的桌子上进行了测试(最好的10个).在Postgres 9.1中,get_byte()实际上要快一点:
CREATE TEMP TABLE t (a bytea); INSERT INTO t SELECT (12345670000000 + generate_series(1,10000))::text::bytea;
比特移位与乘法/加法一样快:
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,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