人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

javaのjava.sql.PrepareStatementのexecuteUpdateメソッドを使用しOracleにデータ登録した際、
設定された値とは異なる値が登録されるという事象が発生しました。

事象は極まれにのみ発生し、ソースコードを追ってみても問題点が見つかりません。

事象を簡単にまとめると、
1.コネクション接続

2.SQL文生成
String sql =
"INSERT INTO TEST_TABLE(ID, NAME, UPDATE_TIME) VALUES ( ? , ? , SYSDATE )";

3.SQL実行
PrepareStatementに、setObjectメソッドで、
値を設定する。
一つ目のデータ:"1"(String型)
二つ目のデータ:"3"(String型)

その後、PrepareStatementのexecuteUpdateメソッドで処理を実行する。

上記処理で稀にTEST_TABLE.NAMEに「3」ではなく「0」が入っているものがあった。

Oracleバージョン:Oracle10g(10.1.0.2.0)
javaバージョン:1.4.2_06

該当テーブル仕様
-------------------------------------
カラム名 型 長さ NOT NULL
-------------------------------------
ID NUMBER (8,0) NOT NULL
MEMBER_NO NUMBER (4,0)
UPDATE_TIME DATE

より詳細な情報を追記します。

●質問者: f_kennedy
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:2.0 Java name Number Oracle
○ 状態 :終了
└ 回答数 : 3/3件

▽最新の回答へ

1 ● kato-s
●27ポイント

回答ではないのですが、


String型であれば、

setObjectでなく、setStringを使用するようにする。


"3"はリテラルですか?であれば、SQL分に埋めてしまう。


"3"の部分が変数の場合は、本当に変数に"0"が入っていた

可能性が無いかログを出力して見る。


※ソースは問題ないとのことですが、

可能な部分を良ければ公開してみてください。

◎質問者からの返答

>"3"はリテラルですか?であれば、SQL分に埋めてしまう。

変数です。

>"3"の部分が変数の場合は、本当に変数に"0"が入っていた

>可能性が無いかログを出力して見る。

吐かれたログを確認しましたが、"3"がはいっていました。

(SQL実行後の、値を入れたListの値を出力したログで確認。

#private int executeSql

#logger.info(list);


2 ● F57PB
●27ポイント

ざっとソースを拝見しましたが、以下気になりました。


・コネクション取得

DataSourceと、DriverManager両方からConnectionを取得

していますが、実際そうなのでしょうか?


・トランザクション制御

DBAccessで、Connection#setAutoCommit(false)していますが、

どこでコミットしていますか?

トランザクション境界を明確に意識したほうが良いと思います。


・スレッドセーフ性

DBAccessクラスを含め、スレッドセーフ性は確保されていますか?

一般的に、ConnectionやStatement、ResultSetは

インスタンスフィールドに格納しない方が良いです。


・クローズ

Connection、Statement、ResultSetのクローズは確実に行なわれるよう、

finally句で行なうのがセオリーです。


・テーブル仕様に、"NAME"と言うカラムがないようですが。。。

掲載して頂いているソースやテーブル仕様は正しいですか?


あと、P6Spy(www.p6spy.com/)と言うSQLをログ出力するライブラリがあります。

現象を再現できるのであれば、P6Spyを使ってどのようなSQLが実行されている

のかを確認してはどうでしょうか?


この手の問題は、私の経験上、十中八九勘違いか思い込みです。

一歩引いて、ゆっくり見直すこともお勧めします。

◎質問者からの返答

>・コネクション取得

Connection con =

java.sql.DriverManager.getConnection("jdbc:oracle:thin:@「接続先アドレス」:「接続文字列」",「ユーザー名」,「パスワード」);

は、テスト用の文の残りで実際はコメント化されてます。

提示ソースに至らないところがありました。申し訳ありません。

>・トランザクション制御

>・スレッドセーフ性

>・クローズ

上記の理由で変なデータが入ってしまう可能性はありますでしょうか?

>・テーブル仕様に、"NAME"と言うカラムがないようですが。。。

ソースの書き写しを間違ってしまいました。

実際は、

×String sql = "INSERT INTO TEST_TABLE(ID, NAME, UPDATE_TIME) VALUES ( ? , ? , SYSDATE)";

○String sql = "INSERT INTO TEST_TABLE(ID, MEMBER_NO, UPDATE_TIME) VALUES ( ? , ? , SYSDATE)";

です。


3 ● samasuya
●26ポイント

テーブル定義がSQL文とあってないのですが、

Stringで設定した値が空白、NULLとかなんじゃないでしょうか?

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ