转换一个bytea的列OID,同时保留值(Convert a bytea column to OID

2019-06-25 08:06发布

我试图改变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

有没有什么方法可以达到我想要什么?

Answer 1:

类型的Oid的列是刚刚到实际上存储在系统的pg_largeobject表二进制内容的参考。 在存储方面,一个OID一个4字节整数。 在另一方面,类型bytea的字段实际内容。

要转移BYTEA成一个大的物体,一个新的大对象应使用大型对象的类文件API创建:lo_create()得到一个新的OID,那么在写模式lo_open调用(),然后用lo_write写()或lowrite(),然后lo_close()。

这不能合理地只是投来完成。

基本上,你需要写一个〜10行的代码在你的选择(至少一个支持大对象API,包括PLPGSQL)做这种转换的语言。



Answer 2:

我认为最好的答案可以在这里找到格雷斯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'));

我已经尝试过了,就像一个魅力。



Answer 3:

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小提琴。

更多在这个相关答案:

  • 从BYTEA了解投给OID


Answer 4:

我相信它的晚,但对任何人有在未来同样的问题。

我也遇到类似的问题,我直接在列没有过的OID在文本列旧数据。 当我尝试使用与升级的应用程序我也渐渐的数据

我用这个线程的知识来解决这个问题。 我强烈地感到,在这个问题谁绊倒肯定会想看看这个在这里



Answer 5:

为了解决这个问题,我成功地使用从格雷斯Batumbya的博客blob_write过程: http://gbatumbya.wordpress.com/2011/06/ 。



文章来源: Convert a bytea column to OID while retaining values