【问题标题】:PostgreSQL: from OID to ByteaPostgreSQL:从 OID 到 Bytea
【发布时间】:2011-06-29 19:00:13
【问题描述】:

我们已决定从 PostgreSQL 9.0 数据库中的 OIDs 迁移到使用 bytea 列。我正在尝试将数据从一列复制到另一列,但我无法找出正确的查询。这是我最接近的:

update user as thistable set pkcs_as_bytea = (select array_agg(mylargeobject.data) from 
  (select * from pg_largeobject where loid = thistable.pkcs12_as_oid order by pageno) as mylargeobject) where thistable.pkcs12 is not null

这给了我以下错误信息:

ERROR:  column "pkcs_as_bytea" is of type bytea but expression is of type bytea[]

那么正确的查询是什么?

【问题讨论】:

  • array_agg() 返回一个数组,因此错误消息是有意义的。为什么你认为你需要在那里聚合字节?
  • 我需要将不同 oid 行上的 blob 合并到一个列中。有更好的方法吗?

标签: postgresql oid


【解决方案1】:

对于文本数组,您需要类似 array_to_string(anyarray, text) 的东西,但在这种情况下,需要使用 array_to_bytea(largeobjectarray) 来连接所有部分。你必须自己创建这个函数,或者在应用程序逻辑中处理它。

【讨论】:

    【解决方案2】:

    这是一个可以发挥神奇作用的存储过程:

    CREATE OR REPLACE FUNCTION merge_oid(val oid) 
    returns bytea as $$
    declare merged bytea;
    declare arr bytea;
     BEGIN  
       FOR arr IN SELECT data from pg_largeobject WHERE loid = val ORDER BY pageno LOOP
         IF merged IS NULL THEN
           merged := arr;
         ELSE
           merged := merged || arr;
         END IF;
       END LOOP;
      RETURN merged;
    
    END  
    $$ LANGUAGE plpgsql;
    

    【讨论】:

      【解决方案3】:

      另一种不需要自定义函数的方法是使用loread(lo_open(...)) 组合,例如:

      UPDATE user SET pkcs_as_bytea = loread(lo_open(pkcs12_as_oid, 262144), 1000000) WHERE thistable.pkcs12 IS NOT NULL
      

      这段代码有问题,loread 函数需要读取的最大字节数作为第二个参数(我上面使用的1000000 参数),所以如果你的你应该在这里使用一个非常大的数字数据很大。否则,在这么多字节之后内容将被修剪,您将无法将所有数据返回到bytea 字段中。

      如果要从 OID 转换为文本字段,还应该使用转换函数,如下所示:

      UPDATE user SET pkcs_as_text = convert_from(loread(lo_open(pkcs12_as_oid, 262144), 1000000), 'UTF8')
      

      262144是打开模式的标志,40000是hexa,意思是“只读打开”)

      【讨论】:

      • 很棒且解释清楚的解决方案。
      【解决方案4】:

      好吧,我做了这样的事情。我有带有 oid 类型数据的附件表和内容列。我迁移了四个操作:

      ALTER TABLE attachment add column content_bytea bytea
      UPDATE attachment SET content_bytea = lo_get(content)
      ALTER TABLE attachment drop column content
      ALTER TABLE attachment rename column content_bytea to content
      

      【讨论】:

        猜你喜欢
        • 2015-06-08
        • 1970-01-01
        • 2012-07-28
        • 1970-01-01
        • 2021-11-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多