下面是一些示例代码,展示了如何使用服务器端 Perl 进行操作。恼人的是,PG 认为打包/解包操作是不受信任的,因此必须由超级用户使用 plperlu 创建,然后通过 GRANT EXECUTE 将访问权限授予非超级用户。
另一方面,这种语言选择使得处理更复杂的打包结构变得容易,这比基于 SQL get_bytes()/set_bytes() 函数的代码具有显着优势。请参阅Perl 的 pack() 功能。
1)第一步:定义一个代表非打包记录的SQL复合类型。
create type comp as (a smallint, b smallint, c int);
2)制作一个函数将记录值打包到bytea中:
create function pack_comp(comp) returns bytea
as $body$
my $arg=shift;
my $retval = pack("CCL", $arg->{a},$arg->{b},$arg->{c});
# encode bytea according to PG doc. For PG>=9.0, use encode_bytea() instead
$retval =~ s!(\\|[^ -~])!sprintf("\\%03o",ord($1))!ge; # from PG doc
return $retval;
$body$ language plperlu;
3)制作一个函数将bytea解包成复合类型:
create or replace function unpack_comp(bytea) returns comp
as $body$
my $arg=shift;
# decode bytea according to PG doc. For PG>=9.0, use decode_bytea() instead
$arg =~ s!\\(?:\\|(\d{3}))!$1 ? chr(oct($1)) : "\\"!ge;
my ($v,$i,$e)= unpack("CCL", $arg);
return {"a"=>$v, "b"=>$i, "c"=>$e};
$body$ language plperlu;
4) 用法:
# select encode(pack_comp((254,14,1000000)::comp), 'hex');
encode
--------------
fe0e40420f00
# select unpack_comp(decode('fe0e40420f00','hex'));
unpack_comp
------------------
(254,14,1000000)
# select * from unpack_comp(decode('fe0e40420f00','hex'));
a | b | c
-----+----+---------
254 | 14 | 1000000