2011-02-18 72 views
2

我們決定從我們的PostgreSQL 9.0數據庫中的OID中移出,並使用bytea列代替。我試圖將數據從一列複製到另一列,但我無法弄清楚正確的查詢。這是我已經得到了最靠近:PostgreSQL:從OID到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[] 

什麼是正確的查詢呢?

+0

`array_agg()`返回一個數組,所以錯誤信息是有道理的。你爲什麼認爲你需要在那裏聚合字節? – 2011-02-18 12:42:23

+0

我需要將不同oid行上的blob合併到一個列中。有沒有更好的方法來做到這一點? – malaverdiere 2011-02-21 04:37:49

回答

1

下面是一個存儲過程,確實神奇:

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; 
0

對於文本數組,您需要類似array_to_string(anyarray, text)的東西,但在這種情況下,需要使用array_to_bytea(largeobjectarray)來連接所有節。你必須自己創建這個函數,或者在應用程序邏輯中處理這個函數。

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在六,這意味着一個標誌「open read-only」)

相關問題