我试图改变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
有没有什么方法可以达到我想要什么?
类型的Oid的列是刚刚到实际上存储在系统的pg_largeobject表二进制内容的参考。 在存储方面,一个OID一个4字节整数。 在另一方面,类型bytea的字段是实际内容。
要转移BYTEA成一个大的物体,一个新的大对象应使用大型对象的类文件API创建:lo_create()得到一个新的OID,那么在写模式lo_open调用(),然后用lo_write写()或lowrite(),然后lo_close()。
这不能合理地只是投来完成。
基本上,你需要写一个〜10行的代码在你的选择(至少一个支持大对象API,包括PLPGSQL)做这种转换的语言。
我认为最好的答案可以在这里找到格雷斯Batumbya的博客 , 在verbis:
该算法很简单,得到的二进制数据,如果为空,则返回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'));
我已经尝试过了,就像一个魅力。
Postgres的9.4增加了一个内置函数此:
lo_from_bytea(loid oid, string bytea)
从发行说明 :
- 添加SQL函数以允许[大对象的读/写] [12]在任意偏移(帕维尔Stehule)
对于旧版本 ,这是比更有效的已发布之前 :
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
修改是比手动处理空聪明。
SQL小提琴。
更多在这个相关答案:
我相信它的晚,但对任何人有在未来同样的问题。
我也遇到类似的问题,我直接在列没有过的OID在文本列旧数据。 当我尝试使用与升级的应用程序我也渐渐的数据
我用这个线程的知识来解决这个问题。 我强烈地感到,在这个问题谁绊倒肯定会想看看这个在这里
为了解决这个问题,我成功地使用从格雷斯Batumbya的博客blob_write过程: http://gbatumbya.wordpress.com/2011/06/ 。