- PR -

postgres8.1へのラージオブジェクトの格納について

1
投稿者投稿内容
フライト
ベテラン
会議室デビュー日: 2005/03/11
投稿数: 63
お住まい・勤務地: 津田沼・東京
投稿日時: 2006-09-28 19:56
postgres8.1へのラージオブジェクトを格納する事が出来ませんでした。

ラージオブジェクトはjavaのオブジェクトをObjectOutputStreamで貼り付けたファイルです。
#javaのオブジェクトをそのままDBへ格納するのはなるべくしたくなかったので


エラー内容で検索してみたのですが英語のメールのログでよく分かりませんでした。


エラーの内容
-------------
org.postgresql.util.PSQLException: ERROR: column "file" is of type oid but expression is of type bytea
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1527)
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1311)
org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:190)
org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:354)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:308)

・・・

テーブル構造
------------
CREATE TABLE test
(
shopid char( NOT NULL,
file oid,
CONSTRAINT test_pkey PRIMARY KEY (shopid)
)


javaのコード
------------
public void testInsert(File file,String data){

・・・

String SQL_QUERY =
"INSERT "
+" INTO "
+" test( "
+" shopid "
+" ,file "
+" ) "
+" VALUES( "
+" ? "
+" ,? "
+" ) ";

PreparedStatement ps = conn.prepareStatement(SQL_QUERY);
FileInputStream fis = new FileInputStream(file);
ps.setString(1,data);
ps.setBinaryStream(2, fis, (int) file.length());
ps.executeUpdate();
ps.close();


・・・


setBinaryStreamをsetAsciiStreamにした所、エラー内容は以下のようになりました。
エラーの内容
-------------
org.postgresql.util.PSQLException: ERROR: column "file" is of type oid but expression is of type character varying
org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:1527)
org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1311)
org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:190)
org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:452)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:354)
org.postgresql.jdbc2.AbstractJdbc2Statement.executeUpdate(AbstractJdbc2Statement.java:308)


解決策についてアドバイスをいただけないでしょうか?

以上です。

大ベテラン
会議室デビュー日: 2006/06/28
投稿数: 116
投稿日時: 2006-09-28 23:09
当方postgresを使用した経験が非常に少なく今回のような使用法は行ったことがないため以下はあまり正しくないかもしれませんが、
エラーメッセージを意訳すると「DBのfileカラムの型がoidなのに格納値はbytea型ですよ」でしょうか。

解決法ですが、BLOBを使えないでしょうか?
と思って検索してみました。
jdbc blob oid
のキーワードで検索するとそれらしいサイトがヒットします。(詳細見てませんのでそれらしいとしか言えないですが)
フライト
ベテラン
会議室デビュー日: 2005/03/11
投稿数: 63
お住まい・勤務地: 津田沼・東京
投稿日時: 2006-09-29 11:06
暁さん

返答ありがとうございます。

テーブルのoidの箇所をbyteaに変えて再度試してみた所うまくいきました。

私にBLOB、CLOBの知識が足りなかったようです。

ラージオブジェクトの型は、oid型しか存在しないと思っていたのですがbytea型という型も存在したのですね・・

まだ試してみてはいないのですが、oid型でもsetBlob(INT,Blob)を使えばいけそうな感じがしてきました。
javaの仕様を見るとsetBytes(INT,byte)でも行けそうに感じますが、PostgreSQLのJDBCドライバでは未実装っぽいですね。。

大ベテラン
会議室デビュー日: 2006/06/28
投稿数: 116
投稿日時: 2006-09-29 21:54
解決して何よりです。
ですが、byteaは用途とサイズなどよく考えて使わないと、使い勝手が悪くなるようです。
以下、調べてみました結果を記述します。参考になれば幸いです。

oidが用意されているということはbyteaにサイズ制限でもあるのか…と思ったのですが、
サイズ制限というより格納方法が異なるようです。
なおbyteaは可変のバイナリ格納型のようなのですが、ラージオブジェクト格納用としては認識されていないようです。

以下サイトでPostgreSQLへのバイナリ格納の実験結果が記述されていましたhttp://mikilab.doshisha.ac.jp/dia/research/report/2003/0606/001/report20030606001.html

これを見る限りではbyteaでは実用上サイズ制限が発生しそうです。
1

スキルアップ/キャリアアップ(JOB@IT)