我正在使用PostgreSQL 9.2
This blog entry by Grace Batumbya提供了从bytea
到oid
的演员表。
create or replace function blob_write(lbytea bytea)
returns oid
volatile
language plpgsql as
$f$
declare
loid oid;
lfd integer;
lsize integer;
begin
if(lbytea is null) then
return null;
end if;
loid := lo_create(0);
lfd := lo_open(loid,131072);
lsize := lowrite(lfd,lbytea);
perform lo_close(lfd);
return loid;
end;
$f$;
CREATE CAST (bytea AS oid) WITH FUNCTION blob_write(bytea) AS ASSIGNMENT;
CREATE TABLE bytea_to_lo (
largeObj lo
);
我不明白我们为什么要创建bytea_to_lo
表?如何PostgreSQL
使用它?
答案 0 :(得分:1)
演员不是真正的演员。它只是(ab)使用方便的语法。在后台创建large object (LO),单独存储,并返回引用它的OID。
所有大对象都存储在一个名为的系统表中
pg_largeobject
。每个大对象在系统中也有一个条目 表格1}}。可以创建,修改大对象, 并使用类似于标准的读/写API删除 对文件的操作。
返回的OID基本上是系统表pg_largeobject
的PK的FK。
pg_largeobject_metadata
完全独立于函数和伪转换。
CREATE TABLE
这只是上面创建的赋值转换的典型用例,从您忘记引用的以下行中可以看出这一点:
CREATE TABLE bytea_to_lo (
largeObj lo
);
数据类型INSERT INTO bytea_to_lo VALUES (DECODE('00AB','hex'));
是基本类型lo
上的域,由附加模块lo
创建(在blog enty of Grace Batumbya中错误地称为“lo_manage包”) 。 Per documentation:
该模块还提供了一种数据类型
oid
,它实际上只是一个域lo
类型的。这对于区分数据库列很有用 持有来自其他东西的OID的大对象引用。
函数decode()
返回oid
。 bytea
语句将INSERT
值分配给列bytea
,这会触发转换为其类型largeObj
的赋值,这就是上面的转换所在的位置。
博客条目现在已经过时了,过时了。
无需提及(per documentation):
要创建演员表,您必须拥有源或目标 数据类型,对另一种类型具有
lo
权限。
实际上,您必须是超级用户。
USAGE
中的错字:列名称和类型已反转。
功能定义冗长且效率低下。这样会更好(对于Postgres 9.3 或更早):
CREATE TABLE
Postgres 9.4 中有built-in function。请改用:
CREATE OR REPLACE FUNCTION blob_write(bytea)
RETURNS oid AS
$func$
DECLARE
loid oid := lo_create(0);
lfd int := lo_open(loid,131072); -- = 2^17 = x2000
-- symbolic constant defined in the header file libpq/libpq-fs.h
-- #define INV_WRITE 0x00020000
BEGIN
PERFORM lowrite(lfd, $1);
PERFORM lo_close(lfd);
RETURN loid;
END
$func$ LANGUAGE plpgsql VOLATILE STRICT;
- 添加SQL函数以允许large object reads/writes处于任意偏移量(Pavel Stehule)
lo_from_bytea(loid oid, string bytea)
(per documentation):
第一个参数类型必须与cast的源类型相同或二元可强制化。
我建议使用只有CREATE CAST
参数的重载变体:
bytea
由于伪演员具有相当大的副作用,我不相信会成为CREATE OR REPLACE FUNCTION lo_from_bytea(bytea)
RETURNS oid LANGUAGE sql AS
'SELECT lo_from_bytea(0, $1)';
CREATE CAST (bytea AS oid) WITH FUNCTION lo_from_bytea(bytea) AS ASSIGNMENT;
演员。我可能会从仅显式开始: