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_output为hex,这是自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)
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)
| 归档时间: |
|
| 查看次数: |
5862 次 |
| 最近记录: |