簡體   English   中英

在保留值的同時將bytea列轉換為OID

[英]Convert a bytea column to OID while retaining values

我正在嘗試更改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()。

僅僅通過演員表演無法合理地做到這一點。

基本上,您需要使用您選擇的語言(至少一個支持大對象API的代碼,包括plpgsql)編寫~10行代碼來執行此轉換。

我認為最好的答案可以在Grace Batumbya的博客 中找到

算法非常簡單,獲取二進制數據,如果為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'));

我試過它,就像一個魅力。

Postgres 9.4為此添加了一個內置函數

lo_from_bytea(loid oid, string bytea)

發行說明

  • 添加SQL函數以允許[大對象讀/寫] [12]在任意偏移處(Pavel 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修飾符比手動處理NULL更聰明。

SQL小提琴。

更多相關答案:

我確信它已經很晚了,但對於今后遇到同樣問題的人來說。

我還遇到了一個類似的問題,我在文本列中的舊數據直接在列中而不是OID。 當我試圖將這些數據用於升級的應用程序時,我也得到了

我用這個線程的知識來解決這個問題。 我強烈地感到無論誰遇到這個問題都肯定會在這里看一看

為了解決這個問題,我成功地使用了Grace Batumbya博客的blob_write程序: http ://gbatumbya.wordpress.com/2011/06/。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM