- PR -

JDBC接続方法違いでエラーとなる。

投稿者投稿内容
ken
常連さん
会議室デビュー日: 2002/04/29
投稿数: 38
投稿日時: 2003-09-08 15:35
単なる勘ですが
ResultSet の getBytes(...)メソッド
はどうでしょうか?
taku
ぬし
会議室デビュー日: 2002/11/12
投稿数: 918
お住まい・勤務地: 墨田区→中野区
投稿日時: 2003-09-08 15:39
引用:

S38さんの書き込み (2003-09-08 15:30) より:
ニシトミさん、藍空さん、R−55さん返信ありがとうございます。
S38です。
resultsetにgetBlobメソッドがないんですけれども、
OracleResultSetクラスにgetBLOBメソッドがあります。
(なんでClass.forNameクラスで接続するといいのかな?)

誠に申し訳ございませんが、引き続きお願い致します。


J2SDK1.2以降ならjava.sql.ResultSetもgetBlobを持っているはずです。
※サンのJavaドキュメントを参照のこと
R-55
常連さん
会議室デビュー日: 2003/03/13
投稿数: 29
投稿日時: 2003-09-08 15:49
あまりいいアドバイスはできなかったようですが・・・。

一度両方の場合でconnection,statement,resultSetなどの
実際のクラス名を表示させてみたらどうでしょうか?
S38
会議室デビュー日: 2003/07/07
投稿数: 10
投稿日時: 2003-09-08 16:41
takuさん
ご指摘ありがとうございます!! 持っていました。
みなさん、大変失礼しました。JAVA初心者の為、今後ともよろしくです。

藍空さんより
Blob blob = resultset.getBlob("blob_col");
OutputStream out = ((BLOB)blob).getBinaryOutputStream();
で実行したところ      ↑ここでエラーとなってしまいました。
ClassCastExceptionです。

kenさんのをヒントに
Blob blob = resultset.getBlob("blob_col");
OutputStream out = blob.setBinaryStream(0);
で実行したところ
エラーメッセージ
HTTP Status 500 -
-------------------------------------------------------------------------------
type Exception report
message
description The server encountered an internal error () that prevented it from fulfilling this request.
exception
javax.servlet.ServletException: サーブレットの実行により例外を投げました
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:193)
省略

root cause
java.lang.AbstractMethodError: oracle.sql.BLOB.setBinaryStream(J)Ljava/io/OutputStream;
at db_operation.Coracle.bin_insert2(Coracle.java:148)
となってしまいました。

なかなか、うまいこといきません。
アドバイスのテスト確認をするのにかなり手間取っています。
引き続きよろしくお願い致します。

S38
会議室デビュー日: 2003/07/07
投稿数: 10
投稿日時: 2003-09-08 19:05
引用:

R-55さんの書き込み (2003-09-08 15:49) より:
あまりいいアドバイスはできなかったようですが・・・。

一度両方の場合でconnection,statement,resultSetなどの
実際のクラス名を表示させてみたらどうでしょうか?



クラスの内容を取得しました。
内容に差がありますが、この情報をどの様に活用したらよいか
わかりませんので、すいませんがご教授よろしくお願い致します。
<--のABCはどうやら同じ内容が格納されている様です。

【class.forNameクラス】
(1)connection= OracleConnection  <---A
(2)statement= OracleStatement   <---B
(3)resultset= OracleResultSetImpl <---C

【データソース活用】
(1)connection= PoolableConnection
_closed= false
_conn= OracleConnection      <---A 
_pool= AbandonedObjectPool
config= null
createdBy= null
createdDate= null
lastUsed= 1063010475905
parent= null
trace= ArrayList

(2)statement= DelegatingStatement
_closed= false
_conn= PoolableConnection
_stmt= OracleStatement      <---B
config= null
createdBy= null
createdDate= null
lastUsed= 1063010690944
parent= null
trace= ArrayList

(3)resultset= DelegatingResultSet
_res= OracleResultSetImpl    <---C
_stmt= DelegatingStatement
config= null
createdBy= null
createdDate= null
lastUsed= 0
parent= null
trace= ArrayList

上記の情報はECLIPSEのデバックモードで確認しました。
だだ
会議室デビュー日: 2003/09/08
投稿数: 2
投稿日時: 2003-09-08 19:40
初めまして。

悩んでいる内容ですが、ドライバにthinを使用してさらに、Blobを使用している際のデータ格納であると捉えていますがそれで良いでしょうか。だとするとまず、Blobを使用する場合は、PreparedStatementを使う必要があります。
で、ociドライバを使う場合は、通常のinsertコマンドで大丈夫ですが、thinドライバの場合はさらに、OraclePreparedStatementを使わなくてはなりません。

以下にサンプルを添付しますので参考にしてみて下さい。


-- 表スクリプト --
CREATE TABLE TABBLOB
(ID NUMBER(4,0) NOT NULL
,NAME VARCHAR2(20)
,IMG BLOB
)
/
ALTER TABLE TABBLOB
ADD CONSTRAINT TABBLOB_PK PRIMARY KEY
(ID)
/
------------------

-- 上記表に画像を挿入するサンプル・プログラム --
package tar1;

import java.io.*;
import java.sql.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;

public class ImageInsertApp1 {


public ImageInsertApp1() {
}

public static void main(String[] args) {

// 環境にあわせて以下の6つの値を変更してください
String dbuser = "scott";
String dbpassward = "lion";
String connectstring = "jdbc:oracle:thin:@vlaovic:1521:ora815";
int id = 10;
String name = "fw.jpg";
String imgdata = "d:\\vlaovic.jpg";


try {
Class c = Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(
connectstring,dbuser,dbpassward);
conn.setAutoCommit(false);

// 1 BLOBエントリを表内に作成
OraclePreparedStatement ps = (OraclePreparedStatement)
conn.prepareStatement("insert into tabblob values(?,?,empty_blob())");
ps.setInt(1,id);
ps.setString(2,name);
ps.execute();
conn.commit();
ps.close();

// 2 表からBLOBロケータを取得
Statement stmt = conn.createStatement();
ResultSet rset = stmt.executeQuery("Select img from tabblob where id ="
+ id + " for update");
rset.next();
BLOB bdata = ((OracleResultSet)rset).getBLOB(1);

// 3 ファイル・ハンドラを宣言し、ストリームを作成
File binaryFile = new File(imgdata);
System.out.println(imgdata + " length = " + binaryFile.length());
FileInputStream instream = new FileInputStream(binaryFile);
OutputStream outstream = bdata.getBinaryOutputStream();

// 4 BLOBに書き込むための理想的なチャンク・サイズを決定しバイト配列の作成
int chunk = bdata.getChunkSize();
byte[] buffer = new byte[chunk];
int length = -1;

// 5 ストリームを使用してBLOBに書き込み
while ((length = instream.read(buffer)) != -1) {
outstream.write(buffer,0,length);
}
instream.close();
outstream.close();
conn.commit();
rset.close();
stmt.close();
conn.close();


System.out.println("Insertion successed.");



}
catch(Exception e1){
e1.printStackTrace();
}

}
}
-------------------------------------------

-- 上記表内のデータからファイルを作成するサンプル・プログラム --
package tar1;

import java.io.*;
import java.sql.*;
import oracle.jdbc.driver.*;
import oracle.sql.*;

public class ImageSelectApp1 {


public ImageSelectApp1() {
}

public static void main(String[] args) {

// 環境にあわせて以下の4つの値を変更してください
int id = 10;
String dbuser = "scott";
String dbpassward = "lion";
String connectstring = "jdbc:oracle:thin:@vlaovic:1521:ora815";

try {
Class c = Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(
connectstring,dbuser,dbpassward);
Statement stmt = conn.createStatement();

// 設定したidのBLOBデータを取得する
ResultSet rset = stmt.executeQuery(
"select name,img from tabblob where id =" + id);
rset.next();

String name = rset.getString(1);
BLOB bdata = ((OracleResultSet)rset).getBLOB(2);
long length2 = bdata.length();

// 取得したBLOBデータより、d:\ディレクトリに取得した名前で
// ファイル作成
FileOutputStream foutstream = new FileOutputStream(
"d:\\" + name,false);
InputStream instream = bdata.getBinaryStream();
int chunk = bdata.getChunkSize();
byte[] buffer = new byte[chunk];
int length = -1;
while ((length = instream.read(buffer)) != -1) {
foutstream.write(buffer,0,length);
}

foutstream.flush();

instream.close();
foutstream.close();
rset.close();
stmt.close();
conn.close();


}
catch(Exception e1) {
e1.printStackTrace();
}


}
}

---------------------------------------------------------
S38
会議室デビュー日: 2003/07/07
投稿数: 10
投稿日時: 2003-09-08 20:50
たださん、ソースサンプルありがとうございます。

たださんのソースの以下の部分
Class c = Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection(
connectstring,dbuser,dbpassward);
を、データソースを活用した
InitialContext ic;
DataSource ds;
ic = new InitialContext();
ds = (DataSource)ic.lookup("java:comp/env/jdbc/ora815");
connection = ds.getConnection();
にてDB接続し実装したいのですが・・・
BLOB型のキャストエラー等発生していて
うまいこといかない状況です。

javan
会議室デビュー日: 2003/03/03
投稿数: 18
投稿日時: 2003-09-08 21:38
だださんの書き込みより
引用:
だとするとまず、Blobを使用する場合は、PreparedStatementを使う必要があります。


PreparedStatementでなければならない訳ではないですよ。
java.sql.Statementでもよいはずです。

Blob以外のDB操作はデータソースの使用でもないのですよね?

[ メッセージ編集済み 編集者: javan 編集日時 2003-09-08 21:39 ]

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