5

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

私が望むものを達成する方法はありますか?

4

5 に答える 5

6

Oid 型の列は、システムのpg_largeobjectテーブルに実際に格納されているバイナリ コンテンツへの単なる参照です。ストレージに関しては、Oid は 4 バイトの整数です。一方、タイプ bytea の列は実際の内容です。

バイトをラージ オブジェクトに転送するには、ラージ オブジェクトのファイルに似た API を使用して、新しいラージ オブジェクトを作成する必要があります。新しい OID を取得するには、lo_create() を使用し、その後、書き込みモードで lo_open() を使用してから、lo_write() を使用して書き込みます。 lowrite()、そして lo_close()。

これは、キャストだけでは合理的に行うことができません。

基本的に、この変換を行うには、選択した言語 (少なくとも plpgsql を含むラージ オブジェクト API をサポートする言語) で ~10 行のコードを記述する必要があります。

于 2012-04-13T10:51:49.220 に答える
5

Postgres 9.4では、このための組み込み関数が追加されています。

lo_from_bytea(loid oid, string bytea)

リリースノートから:

  • 任意のオフセットで [大きなオブジェクトの読み取り/書き込み][12] を許可する SQL 関数を追加しました。 (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 フィドル。

この関連する回答の詳細:

于 2015-04-03T17:05:19.000 に答える
0

遅いと確信していますが、将来同じ問題を抱えている人にとっては.

OID としてではなく、テキストの列に直接古いデータが含まれているという同様の問題にも直面しました。そして、アップグレードされたアプリケーションでそのデータを使用しようとしたときに、私も取得していました

このスレッドの知識を使用して、この問題を解決しました。この質問に出くわした人は誰でも、きっとここでこれを見たいと思うでしょう。

于 2015-04-07T05:25:45.130 に答える
-1

この問題を解決するために、Grace Batumbya のブログ ( http://gbatumbya.wordpress.com/2011/06/ ) の blob_write プロシージャを使用して成功しました。

于 2012-08-28T08:58:53.710 に答える