- - PR -
PreparedStatementについて
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-02-12 21:01
そうです。
正しいSQL文を実行して例外が投げられることはありません。 | ||||||||
|
投稿日時: 2004-02-12 21:52
where句の user_id = ?で
更新レコードがなかっただけでは? 変数の値を確認するとわかると思います。 | ||||||||
|
投稿日時: 2004-02-12 22:16
ご指摘まことに有難うございました。
非常にお騒がせしてしまいまして、まことに申し訳ございません。。。 原因はどうやら、変数"user_id"にあったようです。 このuser_idには、DB上の"USERID"という列に格納されている いずれかの値が入るのですが、このUSERID列は、CHAR型の16桁となっております。 しかし、変数"user_id"の中身の値は16桁に満たない値が入っていたために 条件にマッチしなかった可能性が高いです。。。 このような時は、CHAR型→VARCHAR型への変更をせざるを得ないのでしょうか。。。(^^; | ||||||||
|
投稿日時: 2004-02-13 08:52
こんにちわ。
USERID列の値をTRIMしてからuser_idとマッチさせるか、 user_idが16桁になるように空白でPADDINGしてからマッチさせてはいかがですか? #USERID列の16桁に満たない部分が空白で埋まっていると仮定していますが… | ||||||||
|
投稿日時: 2004-02-13 09:35
TRIMをかけてしまうとインデックスが働かなくなると思いますので、 足らない桁数だけ空白埋めしたほうがよいかと思われます。 まあ、この手のテーブルは件数がそれほど多く無いと思われるので、 体感速度は変らないでしょうけど。 | ||||||||
|
投稿日時: 2004-02-13 11:54
こんにちわ。
たしかにUSERIDなんていう名前のカラムはINDEXが張ってありそうですね… そこまで考えてませんでした というわけで、Indexを張っているならば takuさんの仰るようにパディングしたほうがよさそうです。 [ メッセージ編集済み 編集者: ゆう 編集日時 2004-02-13 11:55 ] | ||||||||
|
投稿日時: 2004-02-13 14:30
takuさん、ゆうさん、ご回答どうも有難うございます!
>TRIMをかけてしまうとインデックスが働かなくなると思いますので、 >足らない桁数だけ空白埋めしたほうがよいかと思われます。 上記は、「PreparedStatementを使用しているActionの中で、変数user_idを取得した 際に16桁に満たない部分は、空白を埋めてしまう」という意味ですよね? じつは、PreparedStatementを使用する前は、普通のStatementを使用して 以下のようなコードにしておりました。 Statement stmt = con.createStatement(); String sql = "UPDATE ZRDBB01Z SET"; sql = sql + " PASSWD='" + hash_pass + "'"; sql = sql + " where (userid='" + user_id +"')"; int result = stmt.executeUpdate(sql); 上記のStatementを使用していた際には、変数user_idに16桁以内の値が入った時でも 問題なく動作しておりました。(Statementは自動で、足りない空白を埋めてくれたりしてるんですかね?) ただ、上記だと変数"hash_pass"に「'」が含まれる場合があり、その場合は SQL文が壊れてしまい、SQLエラーとなる場合があります。 「'」が含まれた場合のエスケープ処理をPreparedStatementが自動で 行ってくれると聞きましたので、今回PreparedStatementを使用しようと 苦労している背景があったりします。 | ||||||||
|
投稿日時: 2004-02-13 14:48
PreparedStatement の仕様です(少なくとも、Oracle JDBC 上では)。
「Oracle JDBC開発者ガイドおよびリファレンス リリース1(9.0.1)」(pdfファイル)の 6-17 ページ、「WHERE 句に CHAR データをバインドするためのメソッド、setFixedCHAR」 を参照してください。 ### 以下、追記 当該ページを引用します。 > データベース内のCHAR データは、列幅まで埋め込まれます。このため、SELECT 文の > WHERE 句に文字データをバインドするためのsetCHAR() メソッドの使用に関して、制限が > 生じます。つまり、WHERE 句の文字データも、SELECT 文で合致させるために、列幅まで埋 > め込む必要があります。これは特に列幅がわからない場合に問題になります。 > これを修正するために、Oracle はOraclePreparedStatement クラスに > setFixedCHAR() メソッドを追加しました。このメソッドは埋込みなしの比較を実行しま す。 使用例 > ((OraclePreparedStatement)pstmt).setFixedCHAR(1, "JDBC"); [ メッセージ編集済み 編集者: 顔爺 編集日時 2004-02-13 14:57 ] | ||||||||
