- PR -

ファイルデータのバイナリデータ化について

投稿者投稿内容
常連さん
会議室デビュー日: 2004/05/17
投稿数: 23
投稿日時: 2005-03-17 11:26
いつもお世話になっております。
2M以下のファイルをアップロードし、データをSQL Serverのvarbinary型として保持したいのですが、データをSQL Serverに挿入した時点でおかしくなってしまいます。
申し訳ありませんが、おかしいところがあったら指摘していただきたく よろしくお願いします
SQL Server の指定:varbinary型 長さ2048

ファイルをアップロードする際、データはFormFile型で取得します

以下コード--------------------------------------------------------------------
InputStream in = FileData.getInputStream(); ※FileDataはFormFile型です
byte[] byteArr = new byte[filesize];

int c;
int i = 0;

while((c = in.read()) != -1){
byteArr[i] = (byte)c;
i ++;
}

strSQL ="";
strSQL ="INSERT INTO File ";
strSQL +="(File_Data) ";
strSQL +="VALUES ("CONVERT(varbinary(2048),'"+ byteArr + "'))";
---------------------------------------------------------------------------


未記入
ぬし
会議室デビュー日: 2004/09/17
投稿数: 667
投稿日時: 2005-03-17 12:16
そのクエリ文字列を組み立てる方法だと、byteArr.toString() の値が格納されるだけ。Statement#setBinaryStream() を使ったらどう?
かずくん
ぬし
会議室デビュー日: 2003/01/08
投稿数: 759
お住まい・勤務地: 太陽系第三惑星
投稿日時: 2005-03-17 12:30
確証は無いですが,

InputStream#read()ではなく、
InputStream#read(byte[] b, int off, int len)を使ってみてはどうでしょう?

#追記
すみません。この方法、読み込みを高速化できるだけで、回答にはなっていません。


[ メッセージ編集済み 編集者: かずくん 編集日時 2005-03-17 12:44 ]
常連さん
会議室デビュー日: 2004/05/17
投稿数: 23
投稿日時: 2005-03-17 15:34
お答えありがとうございます。
StatementとはPreparedStatementの事でしょうか?
Statement#setBinaryStream()を使用して たとえば、ファイルは複数アップロード出来、既存のデータがある場合はUpDate、ない場合はInsert と処理を分けることは可能でしょうか?
山本 裕介
ぬし
会議室デビュー日: 2003/05/22
投稿数: 2415
お住まい・勤務地: 恵比寿
投稿日時: 2005-03-17 15:44
「ファイルは複数アップロード」と「既存のデータがある場合はUpDate、ない場合はInsert と処理を分ける」の関連性がよくわからないのですが、別の話ですか?
どちらも可能だと思いますが、バイナリストリームを扱うかどうかとは別の次元の話ではないでしょうか?
SQL を発行する前に if 文で分岐するだけで、バイナリストリームだろうが、数値だろうが同様の処理ではないかと思います。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-03-17 15:47
引用:

Statement#setBinaryStream()を使用して たとえば、ファイルは複数アップロード出来、既存のデータがある場合はUpDate、ない場合はInsert と処理を分けることは可能でしょうか?



ん?if文の書き方がわからないと言う事ですか?

逆に、バイナリを扱わないSQLであれば
既存のデータの有無で処理を分ける判断はできるということですか?
常連さん
会議室デビュー日: 2004/05/17
投稿数: 23
投稿日時: 2005-03-17 16:07
よく見たら質問になってませんでした
すみませんでした

例えば

strSQL ="";
strSQL ="INSERT INTO File ";
strSQL +="(ID, File_Data) ";
strSQL +="VALUES (1, ?))";

stmt = con.prepareStatement(strSQL);

stmt.setBinaryStream(1,in,FileSize);

stmt.addBatch();

とします。
この後にstmtに


strSQL ="";
strSQL = "UPDATE File SET ";
strSQL += "ID = 2,";
strSQL += "File_Data = ?,";

stmt.setBinaryStream(1,in,FileSize);

stmt.addBatch();
という処理を追加したいのですが、追加の仕方がわからないのです。
なぜなら 2つの処理が成功した上でcommitしたいのです。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-03-17 16:16
追加したらどうなるのでしょうか?
追加できないと言うのは、コンパイラがコンパイルしてくれないのでしょうか?
追加して実行するとエラーになるということですか?

新たにステートメントを作り直せばいいんじゃないですかね。
コミット・ロールバックっていうのはステートメント単位ではありません。
接続単位で行われますので、同一のConnectionでステートメントを
複数回生成してもクローズが行われていれば問題ありません。

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