- PR -

ストアドでの複数レコード追加

投稿者投稿内容
ATS
会議室デビュー日: 2003/09/03
投稿数: 2
投稿日時: 2003-09-04 01:02
初めて投稿いたします。よろしくお願いします。

現在Java+Oracleでバッチ処理を作成しているのですが、
できるだけストアド(PL/SQL)を利用したいと考えています。
(というか命令です・・・)

私はストアド未経験でして、慌てて調べてみたのですが、
Javaからのストアド呼び出しは下記のような記述で行えることは理解しました。

java.sql.CallableStatement st =
Conn.prepareCall("{call hoge (?,?,?)}");

hogeがレコード追加のプロシージャだとして、
setXXXで各カラムの値を設定して実行してやれば、
とりあえず1件のレコード追加はでるだろうと思います。

そこで質問なのですが、複数件のレコード追加をする場合、
どのようにストアドを実行させるのが良いのでしょうか?

真っ先に思いついたのは、
1.100レコード追加したければ、100回ストアドを実行
これだとパフォーマンス的にどうなんでしょう?
わざわざストアドにする意味がないような・・・

2.ストアド実行は1回で、ストアド内でレコード追加を繰り返し
こちらのほうが賢そうだと思ったのですが、
複数件のレコードの値をストアドに渡す方法が分かりませんでした。
配列のようなものを引数にすることは可能なのでしょうか?
それとも、カンマ区切りの値を渡してやるとか・・・

自分だったらこうする!という手順を、よろしければ教えて下さい。
swat
常連さん
会議室デビュー日: 2002/03/21
投稿数: 33
お住まい・勤務地: 埼玉県
投稿日時: 2003-09-04 09:16
swatです。

試していないので、なんともいえませんが、CallableStatementのaddBatchメソッドで、実現できるかもしれません。

http://java.sun.com/j2se/1.3/ja/docs/ja/guide/jdbc/getstart/callablestatement.html

taku
ぬし
会議室デビュー日: 2002/11/12
投稿数: 918
お住まい・勤務地: 墨田区→中野区
投稿日時: 2003-09-04 09:47
引用:

swatさんの書き込み (2003-09-04 09:16) より:
swatです。

試していないので、なんともいえませんが、CallableStatementのaddBatchメソッドで、実現できるかもしれません。

http://java.sun.com/j2se/1.3/ja/docs/ja/guide/jdbc/getstart/callablestatement.html




 PreparedStatementのaddBatchですね。
addBatchで貯めて、executeBatchでSQLを実行します。
ストアドは使わないので、PreparedStatementでしか使用したことはありませんが。

 DBによっては、複数件のレコードを一回のSQL文でインサートできますが、
Oracleでは無理なんでしょうか?(^^)。
Clap
常連さん
会議室デビュー日: 2003/02/14
投稿数: 20
投稿日時: 2003-09-04 09:56
こんにちは。
ストアド内で配列(TABLE)を扱うことはできますが、
配列を渡すことは不可能だと記憶してます。
通常はカンマ区切りのデータを渡したりします。

>DBによっては、複数件のレコードを一回のSQL文でインサートできますが、
>Oracleでは無理なんでしょうか?(^^)。
PL/SQLのバルクバインドなどを使えば似たようなことができるかと思います。
kito
ベテラン
会議室デビュー日: 2003/03/24
投稿数: 59
お住まい・勤務地: Osaka
投稿日時: 2003-09-04 14:26
> DBによっては、複数件のレコードを一回のSQL文でインサートできますが、

それって結局、
PreparedStatement ps = conn.prepareStatement("insert into table_a (id, name) values(?,?);insert into table_a (id, name) values(?,?)");
ps.setInt(1, 1);
ps.setString(2, "name1");
ps.setInt(3, 2);
ps.setString(4, "name2");
ps.executeUpdate();
みたいなことになりますよね?(insertの構文が多少変わるにしても)

それなら
PreparedStatement ps = conn.prepareStatement("insert into table_a (id, name) values(?,?)");
ps.setInt(1, 1);
ps.setString(2, "name1");
ps.addBatch();
ps.setInt(1, 2);
ps.setString(2, "name2");
ps.addBatch();
ps.executeBatch();
の方がスマートかな、と。


[ メッセージ編集済み 編集者: kito 編集日時 2003-09-04 14:36 ]
taku
ぬし
会議室デビュー日: 2002/11/12
投稿数: 918
お住まい・勤務地: 墨田区→中野区
投稿日時: 2003-09-04 14:49
引用:

kitoさんの書き込み (2003-09-04 14:26) より:
> DBによっては、複数件のレコードを一回のSQL文でインサートできますが、

それって結局、
PreparedStatement ps = conn.prepareStatement("insert into table_a (id, name) values(?,?);insert into table_a (id, name) values(?,?)");
ps.setInt(1, 1);
ps.setString(2, "name1");
ps.setInt(3, 2);
ps.setString(4, "name2");
ps.executeUpdate();
みたいなことになりますよね?(insertの構文が多少換わるにしても)

それなら
PreparedStatement ps = conn.prepareStatement("insert into table_a (id, name) values(?,?)");
ps.setInt(1, 1);
ps.setString(2, "name1");
ps.addBatch();
ps.setInt(1, 2);
ps.setString(2, "name2");
ps.addBatch();
ps.executeBatch();
の方がスマートかな、と。


[ メッセージ編集済み 編集者: kito 編集日時 2003-09-04 14:27 ]


 そうですね、私も後者にしています。
前者の場合ですとSQL文の組み立てを行わなければならないので、
どうしてもSQL文は見づらくなってしまいますからね。
(件数は固定ではないので、ループさせたりしますしね)
あくまでもそういった方法もあるということで(^^)。
taku
ぬし
会議室デビュー日: 2002/11/12
投稿数: 918
お住まい・勤務地: 墨田区→中野区
投稿日時: 2003-09-04 14:54
引用:

takuさんの書き込み (2003-09-04 14:49) より:
引用:

kitoさんの書き込み (2003-09-04 14:26) より:
> DBによっては、複数件のレコードを一回のSQL文でインサートできますが、

それって結局、
PreparedStatement ps = conn.prepareStatement("insert into table_a (id, name) values(?,?);insert into table_a (id, name) values(?,?)");
ps.setInt(1, 1);
ps.setString(2, "name1");
ps.setInt(3, 2);
ps.setString(4, "name2");
ps.executeUpdate();
みたいなことになりますよね?(insertの構文が多少換わるにしても)

それなら
PreparedStatement ps = conn.prepareStatement("insert into table_a (id, name) values(?,?)");
ps.setInt(1, 1);
ps.setString(2, "name1");
ps.addBatch();
ps.setInt(1, 2);
ps.setString(2, "name2");
ps.addBatch();
ps.executeBatch();
の方がスマートかな、と。


[ メッセージ編集済み 編集者: kito 編集日時 2003-09-04 14:27 ]


 そうですね、私も後者にしています。
前者の場合ですとSQL文の組み立てを行わなければならないので、
どうしてもSQL文は見づらくなってしまいますからね。
(件数は固定ではないので、ループさせたりしますしね)
あくまでもそういった方法もあるということで

swat
常連さん
会議室デビュー日: 2002/03/21
投稿数: 33
お住まい・勤務地: 埼玉県
投稿日時: 2003-09-04 15:36
引用:

takuさんの書き込み (2003-09-04 09:47) より:
 PreparedStatementのaddBatchですね。



おっと、リンク先のURLをみたら、

(PreparedStatement から継承)

とかいてありましたね。
失礼しました。

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