[英]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更聰明。
更多相關答案:
我確信它已經很晚了,但對於今后遇到同樣問題的人來說。
我還遇到了一個類似的問題,我在文本列中的舊數據直接在列中而不是OID。 當我試圖將這些數據用於升級的應用程序時,我也得到了
我用這個線程的知識來解決這個問題。 我強烈地感到無論誰遇到這個問題都肯定會在這里看一看
為了解決這個問題,我成功地使用了Grace Batumbya博客的blob_write程序: http ://gbatumbya.wordpress.com/2011/06/。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.