- PR -

PreparedStatementのsetStringについて

投稿者投稿内容
さうす
会議室デビュー日: 2008/10/16
投稿数: 8
投稿日時: 2008-10-16 11:41
始めて投稿させていただきます。

環境
windowsxp
java:1.6
Tomcat:5.5
Struts:1.3.8
mysql:4.0

ソース
try {
String sql = "select * from members where userid = ?";
con = getConnection();
stmt = con.prepareStatement(sql);
stmt.setString(1, userid);
rs = stmt.executeQuery();



}

エラー
java.lang.StringIndexOutOfBoundsException: String index out of range: 6
at java.lang.String.charAt(String.java:687)
at com.mysql.jdbc.StringUtils.escapeEasternUnicodeByteStream(StringUtils.java:231)
at com.mysql.jdbc.StringUtils.getBytesWrapped(StringUtils.java:575)
at com.mysql.jdbc.PreparedStatement.setString(PreparedStatement.java:4093)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.setString(DelegatingPreparedStatement.java:132)
at myapp.struts.model.logic.MemberDAO.check(MemberDAO.java:125)
at myapp.struts.action.MemberAction.regist(MemberAction.java:29)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:269)
at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
at org.apache.struts.chain.commands.servlet.ExecuteAction.execute(ExecuteAction.java:58)
at org.apache.struts.chain.commands.AbstractExecuteAction.execute(AbstractExecuteAction.java:67)
at org.apache.struts.chain.commands.ActionCommandBase.execute(ActionCommandBase.java:51)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.commons.chain.generic.LookupCommand.execute(LookupCommand.java:304)
at org.apache.commons.chain.impl.ChainBase.execute(ChainBase.java:190)
at org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:462)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:269)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at myapp.struts.filter.EncodingFilter.doFilter(EncodingFilter.java:30)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:215)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:172)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:117)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:108)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:174)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:875)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:665)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:528)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:81)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:689)
at java.lang.Thread.run(Thread.java:619)

-----------------------------------------------------------------------
String index out of range: 6←これは入力フォームに入力されたuseridの長さと等しいです。
プリコンパイルされたsqlをログ出力(System.out.println(stmt))すると、
com.mysql.jdbc.JDBC4PreparedStatement@b1c0b7: select * from members where userid = ** NOT SPECIFIED **
と出てきます。

stmt.setString(1, userid);
のところを
stmt.setString(1, "'" + userid + "'");
とするとエラーは起きず動作します。

しかし、この状態で登録処理を行いデータベースを見るとシングルコーテーションに囲まれた状態での登録になってしまいます。

何が問題なのか分からず質問させて頂きました。
宜しくお願い致します。

[ メッセージ編集済み 編集者: 未記入 編集日時 2008-10-16 11:45 ]
あしゅ
ぬし
会議室デビュー日: 2005/08/05
投稿数: 613
投稿日時: 2008-10-16 12:07
文字列のエスケープ処理にしくじっているようなので
MySQLのJDBCドライバのバグっぽい気がします。

新しいバージョンのものを試してみてはいかがでしょう。
さうす
会議室デビュー日: 2008/10/16
投稿数: 8
投稿日時: 2008-10-16 13:23
あしゅさん、返信ありがとうございます。
jdbcドライバですが、最新のバージョン(Connector/J 5.1.6)を使用しています。

他にお気づきの点が御座いましたら、ご教授下さいませ。
冬寂
ぬし
会議室デビュー日: 2002/09/17
投稿数: 449
投稿日時: 2008-10-16 13:50
javaには詳しく無いながら、ちょっと興味を持ったので書かせていただきます。

で、思うに
引用:

さうすさんの書き込み (2008-10-16 11:41) より:
stmt.setString(1, userid);
のところを
stmt.setString(1, "'" + userid + "'");
とするとエラーは起きず動作します。


ここが重要なんじゃないかなぁ?
useridの型について教えていただけませんか?
さうす
会議室デビュー日: 2008/10/16
投稿数: 8
投稿日時: 2008-10-16 14:11
冬寂さん、返信ありがとうございます。

useridの型はDBではVarcharで、ソースではStringになっています。

その他お気づきの点が御座いましたら、引き続き宜しくお願い致します。
冬寂
ぬし
会議室デビュー日: 2002/09/17
投稿数: 449
投稿日時: 2008-10-17 10:10
うーむ。元々詳しく無いながら、ますます訳が分からない状態になっていますね・・・

先に指摘した所から、useridが文字列として扱われて居無い、とかそういうものなのかなぁ?とか思ったのですが、そういう訳ではなさそうですね。
もし差し支えなければ、試しに、useridをクォートするのではなくて、適当な文字をつけてみてエラーが出るかどうか調べてみたりするのはどうでしょう?
(もしくは、逆に数値をセットしてみたりして。)

コード:
java.lang.StringIndexOutOfBoundsException: String index out of range: 6 
at java.lang.String.charAt(String.java:687) 


ここの部分からすると、なんかさうすさんのプログラムじゃなくて、ライブラリに何かある?のかもしれない、と思ったのですが、
できれば、別のPCに新しく環境を作ってみて試してみたらどうでしょう?

# 同じ現象が出るソースを貼り付けていただけると、見た方が試して報告してくれるかもしれません。
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2008-10-17 10:16
引用:

さうすさんの書き込み (2008-10-16 11:41) より:
stmt.setString(1, userid);
のところを
stmt.setString(1, "'" + userid + "'");
とするとエラーは起きず動作します。



そもそものデータからして、引用符付きで格納されたりしてるんですかね。
馬鹿馬鹿しいっちゃ馬鹿馬鹿しいけど。
さうす
会議室デビュー日: 2008/10/16
投稿数: 8
投稿日時: 2008-10-17 15:14
冬寂さん、返信ありがとうございます。

>>試しに、useridをクォートするのではなくて、適当な文字をつけてみてエラーが出るかどうか調べてみたりするのはどうでしょう?
(もしくは、逆に数値をセットしてみたりして。)

stmt.setString(1, "a" + userid + "b" ); としてみました。
すると、java.lang.StringIndexOutOfBoundsException: String index out of range: 8
となり、abが付加された文字数でのエラーになりました。

数値のセットはsetStringでのエラーになり、コンパイルが通らなくなりました。

PCは家に一台しかないので、試せません・・・。
別のソースに関しては、わたしのスキル不足にて用意することができませんでした。
が、今回のソースコードは
http://book.mycom.co.jp/support/bookmook/Java_CMS/
こちらにあります。
というのも、この本を見て勉強中でして・・・


Edossonさん、返信ありがとうございます。

デバッグし確認してみましたが、引用符付きということは無さそうでした。

--------------------------------------------------------------------------------

完全に行き詰まっています。
引き続き宜しくお願い致します。

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