我正在尝试将bytea
列更改为类型oid
并仍保留值。
我尝试过使用类似的查询:
ALTER TABLE mytable ADD COLUMN mycol_tmp oid;
UPDATE mytable SET mycol_tmp = CAST(mycol as oid);
ALTER TABLE mytable DROP COLUMN mycol;
ALTER TABLE mytable RENAME mycol_tmp TO mycol;
但这只是给我错误:
ERROR: cannot cast type bytea to oid
有没有办法达到我想要的目的?
答案 0 :(得分:4)
Oid类型的列只是对二进制内容的引用,实际存储在系统的 pg_largeobject 表中。在存储方面,Oid是一个4字节的整数。 另一方面,bytea 类型的列是实际内容。
要将bytea转换为大型对象,应使用大型对象的类文件API创建新的大对象:lo_create()获取新的OID,然后在写入模式下执行lo_open(),然后使用lo_write写入()或lowrite(),然后是lo_close()。
只有演员才能合理地做到这一点。
基本上,您需要用您选择的语言(至少一个支持大对象API的代码,包括plpgsql)编写~10行代码才能进行此转换。
答案 1 :(得分:4)
我认为最好的答案可以在Grace Batumbya's Blog,中找到 :
算法非常简单,获取二进制数据,如果为null,则返回null。否则创建一个大对象,并在lowrite函数中,传递二进制值,而不是文件的路径。
该程序的代码如下。请注意,应安装lo_manage包以使其正常工作。
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( lo largeObj );
INSERT INTO bytea_to_lo VALUES ( DECODE('00AB','hex'));
我尝试过它并且像魅力一样。
答案 2 :(得分:2)
Postgres 9.4 为此添加built-in function:
lo_from_bytea(loid oid, string bytea)
- 添加SQL函数以允许[大对象读/写] [12]在任意偏移处(Pavel Stehule)
对于旧版本,这比has been posted before更有效:
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;
STRICT
修饰符比手动处理NULL更聪明。
更多相关答案:
答案 3 :(得分:0)
我确信它已经很晚了,但对于今后遇到同样问题的人来说。
我还遇到了一个类似的问题,我在文本列中的旧数据直接在列中而不是作为OID。当我试图在升级后的应用程序中使用该数据时,我也得到了
我利用这个线程的知识来解决这个问题。我强烈地感到无论谁遇到这个问题都肯定想看看这个here
答案 4 :(得分:-1)
为了解决这个问题,我成功地使用了Grace Batumbya的Blog:http://gbatumbya.wordpress.com/2011/06/中的blob_write程序。