Prepared Statementがおかしい

このQ&Aのポイント
  • MySQLに対して検索する Prepared Statement について質問します。
  • UPDATE文でエラーが出ますが、INSERT文でも同様にGAEでは通るのですがAWSではエラーになります。
  • Prepared Stateオブジェクトを利用すると、SQLの中身が捉えにくく解決できない状況です。
回答を見る
  • ベストアンサー

Prepared Statementがおかしい

MySQLに対して検索する Prepared Statement について質問します。 現在、 Google App Engine(GAE) で動いていたJavaのアプリケーションを Amazon Web Service(AWS) に移動すべく、ソースの見直しを行っています。 以下のソースを走らせると、GAEのローカルテスト環境では動くものの、AWSのローカルテスト環境では エラーが出てしまいます。 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8"); response.setContentType("text/html"); response.setContentType("charset=utf-8"); PrintWriter out = response.getWriter(); try{ /** データベースへの接続を保持するConnectionクラス */ DBAccess dba = new DBAccess(); Connection conn = dba.getConnection(); PreparedStatement pstmt = null; int staffId = Integer.parseInt(request.getParameter("staffId")); String staffName = request.getParameter("staffName"); String staffSort = request.getParameter("staffSort"); String sql = "UPDATE first_tbl_staff SET staffName=?, staffSort=? WHERE staffId=?"; pstmt = conn.prepareStatement(sql); pstmt.setString(1, staffName); pstmt.setString(2, staffSort); pstmt.setInt(2, staffId); System.out.println("sql================" + sql); int count = pstmt.executeUpdate(sql); ※※※←ここで落ちる if(count == 1){ String res = "["; res += "{\"staffId\":\"" + staffId + "\"}"; res += "]"; out.println(res); } pstmt.close(); conn.close(); } catch(Exception e){ System.out.println("例外発生:" + e ); }finally{ } } } コンソールを見ると、以下のプリントアウト文と例外を出しています。 sql================UPDATE first_tbl_staff SET staffName=?, staffSort=? WHERE staffId=? 例外発生:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?, staffSort=? WHERE staffId=?' at line 1 簡単なUPDATE文ですので、文法的にも間違いないと思いますが、何度やってもGAEでは動作しますが、AWSではエラーとなってしまいます。 それぞれの開発環境ですが、同一のマシン(Windows7 32bit)に2つのEcripseを載せています。 【GAE】 ・Eclipse3.7 ・Java 6 ・Jetty? ・App Engine SDK ・MySQL5.5.27  ・jdbcドライバ:mysql-connector-java-5.1.26-bin.jar 【AWS】 ・Eclipse4.3 ・Java 7 ・Tomcat 7 ・AWS SDK ・MySQL5.5.27  ・jdbcドライバ:mysql-connector-java-5.1.26-bin.jar MySQLはローカルの同一のDB/テーブルを見に行ってます。 UPDATE文でエラーが出ますが、INSERT文でも同様にGAEでは通るのですがAWSではエラーになります。 因みにPrepared Statementオブジェクトではなく Statementオブジェクトを利用すると問題なく動きました。 丸1日かかっていろいろ環境を変えたりしていますが、Prepared Stateオブジェクトを利用すると、SQLの中味が 捉えにくく解決できない状況です。 どなた、ヒントになるようなことがおわかりでしたら、ご指導下さい。 よろしくお願いします。

  • Java
  • 回答数3
  • ありがとう数2

質問者が選んだベストアンサー

  • ベストアンサー
  • amino_pl
  • ベストアンサー率50% (1/2)
回答No.3

失礼しました。 >int count = pstmt.executeUpdate(sql); を int count = pstmt.executeUpdate(); でした。

panasobi
質問者

お礼

amino_plさん、教えて頂いた通り int count = pstmt.executeUpdate(); でエラーが出なくなり、ちゃんとアップデートできるようになりました。 確かに、 pstmt = conn.prepareStatement(sql); って sql を引数にセットしておいて、更に int count = pstmt.executeUpdate(sql); はクドイですよね。 でも変ですねぇ? Google App Engine では pstmt = conn.prepareStatement(sql) で問題なく通ってしまいます。 今再度やってみたのですがやっぱり通ってしまいました。 これって、Google App Engine のSDKがユルクて、AWSのSDKが厳密と いうことでしょうか? それともJava6とJava7の違いでしょうか? 理由はよくわかりませんけど、結果オーライです。 amino_plさん、本当にありがとうございました。 大助かりです。感謝の気持ちで一杯です。 ありがとうございました。

その他の回答 (2)

  • amino_pl
  • ベストアンサー率50% (1/2)
回答No.2

>pstmt = conn.prepareStatement(sql); ↓ pstmt = conn.prepareStatement();

  • LancerVII
  • ベストアンサー率51% (1060/2054)
回答No.1

こんにちは。 確実に同じソースを利用しているのであればよくわかりませんが pstmt.setString(1, staffName); pstmt.setString(2, staffSort); pstmt.setInt(2, staffId); 最後のpstmt.setInt(2,staffId)は pstmt.setInt(3,staffId); ではないでしょうか? 質問する際の転記ミスだったらスミマセン。

panasobi
質問者

お礼

早速の回答ありがとうございました。 「staffSort」を削除してより単純なSQLにしたりいろいろやってみました。投稿するときそのときの変更が残ってしまったものと思われます。 実際のソースでは pstmt.setInt(3,staffId); となっています。 その意味では転記ミスです。 混乱させてゴメンナサイ

関連するQ&A

  • javaの掲示板について

    今現在パスワードを比較して一致していれば削除としたのですがjava.sql.SQLException: Can not issue data manipulation statements with executeQuery().というエラーがtomcatにでます。 サーブレットはこう書いています //削除 if(deleteMessage != null){ String deleteid = request.getParameter("id"); String deletepassword = request.getParameter("deletepassword"); String rspassword = dao.getPassword(deleteid); if (deletepassword.equals(rspassword)){ dao.deleteMessage(delete); success = "削除しました。"; request.setAttribute("success", success); } else{ errorpass = "パスワードが違います。"; request.setAttribute("errorpass", errorpass); } } 比較用のパスワードをデータベースから取り出すDAOはこうしています。 public int deleteMessage(String strid) throws Exception { Vector messageList = new Vector(); int i = 0; Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; try{ conn = this.getConnection(); String sql = "delete from MESSAGE_TABLE where ID = ? "; pstmt = conn.prepareStatement(sql); pstmt.setString(1, strid); rs = pstmt.executeUpdate(); } finally { this.close(rs); this.close(pstmt); this.close(conn); } return i; } public String getPassword(String id) throws Exception { Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; String rspassword = null; try { String deleteid = null; conn = this.getConnection(); String sql = "SELECT * FROM MESSAGE_TABLE where ID = ? "; pstmt = conn.prepareStatement(sql); pstmt.setString(1, id); rs = pstmt.executeQuery(); if(rs.next()){ rspassword = rs.getString("PASSWORD"); } } finally { this.close(rs); this.close(pstmt); this.close(conn); } return rspassword; } データベースからパスワードがとれていないから起きているのだとは思うのですが、どのようにしたらとれるでしょうか? よろしくお願いします。

    • ベストアンサー
    • Java
  • jspのプログラムについて

    jspについて質問です。 現在入力されたパスワードとデータベースに保存してあるパスワードを比較して一緒であれば idを削除するというプログラムを組んでいます。 削除することはできないのですが、 比較がうまくいきません。 <% //postされたもの String id = request.getParameter("id"); String password =request.getParameter("password") Class.forName("com.mysql.jdbc.Driver"); Connection conn=DriverManager.getConnection(urlやpassword、userが書いてある); request.setCharacterEncoding("utf8"); Statement st=conn.createStatement(); Statement stmt=conn.createStatement(); ResultSet res = st.executeQuery("select * from data where id ="+id); while(res.next()){ String pass =res.getString("pass"); //データベースからパスワードを取得 out.println("<td>" + password + "</td>"); out.println("<td>" + pass + "</td>"); if(password==pass){ //入力されたパスワードと比較 //ここにはidを削除する文が書かれている } } st.close(); conn.close(); やっているのですが、if文に入って削除してくれません。 out.printlnはいりませんがちゃんと値があっているか確かめたところ 入力された文字とデータベースに入っている文字がちゃんと表示されました。 教えてください。よろしくお願いします。

  • jspでデータベースにレコード追加

    表題のことをしたいのですが、 「HTTPステータス 500 - An exception occurred processing JSP page」という エラー表示がされてしまいます。 名前、会社、住所というテキストボックスに入力して 決定ボタンを押下するとデータベースにレコード追加されるのを 目的としていますが、下記のコードで間違いはありますでしょうか? ----------------------------------------------- <%@ page language="java" %> <%@ page import="java.sql.*"%> <%@ page contentType="text/html; charset=Shift_JIS"%> <% request.setCharacterEncoding("Shift_JIS"); String strName=request.getParameter("name"); String strCompany=request.getParameter("company"); String strAddress=request.getParameter("address"); Class.forName("com.mysql.jdbc.Driver"); String strConn= "jdbc:mysql://localhost/***" + "?user=****&password=****" + "&useUnicode=true&characterEncoding=Shift_JIS"; Connection conn = DriverManager.getConnection(strConn); Statement stmt = conn.createStatement(); String strSql="insert into person (name,company,address) values('"+ strName + "'," + strCompany + "'," + strAddress + ")"; int result= stmt.executeUpdate(strSql); stmt.close(); conn.close(); %> <%//一覧ページにforward%> <jsp:forward page="****.jsp"/> ----------------------------------------------- >int result= stmt.executeUpdate(strSql); の行でエラーが出ているっぽいのですが。。。 TomcatとMySQLを使用しています。 ※環境など情報が不足していましたら、そちらもご指摘ください。  開発勉強中で、まだ理解が足りていない所が多数あります。

    • ベストアンサー
    • Java
  • JSPとサーブレットの連携

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub request.setCharacterEncoding("windows-31j"); response.setContentType("text/html;charset=windows-31j"); PrintWriter out=response.getWriter(); request.setCharacterEncoding("windows-31j"); String st = request.getParameter("ti"); String s2 = request.getParameter("ho"); String s3 = request.getParameter("ke"); Connection con = null; ResultSet rs = null; Statement stmt = null; try { String url = "jdbc:mysql:///o?user=&password=2&useUnicode=true&characterEncoding=windows-31J"; con = (Connection) DriverManager.getConnection(url); stmt = (Statement) con.createStatement(); String sql = "INSERT INTO o_tb(tiiki,houmon,keiyaku) VALUES('" + request.getParameter("ti")+ "','" + request.getParameter("ho")+ "','" + request.getParameter("ke")+ "') "; int rss=0; rss = stmt.executeUpdate(sql); }catch (SQLException e){ out.println("SQLException:" + e.getMessage()); } JSPから上記のサーブレットに値を渡し、DB格納までは上手くいきました。 ですが当然上記だと真っ白なサーブレットページが表示されるだけです。 JSPのボタンを押し→サーブレットでDB格納したら、またJSPページを表示させたいんですが、どうしたらいいですか??

    • ベストアンサー
    • Java
  • ブラウザ上に表示されたデータベースに追加

    タイトルのことをしようとすると、「java.lang.NullPointerException」というエラーが出ますが、これを解消するにはどうすればよいのでしょうか? そのエラーがでるページのソースを上げておきます。 <%@ page contentType="text/html; charset=Shift_JIS" %> <%@ page import="java.sql.*" %> <%! //toUnicodeメソッドの定義 public String toUnicode(String s) throws java.io.UnsupportedEncodingException { return (new String(s.getBytes("8859_1"), "JISAutoDetect")); } %> <% //JDBCドライバのロード Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); //データベースへ接続 String jdbcUrl = "jdbc:odbc:AnsSheet"; String user = "root"; String password = "progressive"; Connection con = DriverManager.getConnection(jdbcUrl,user,password); //SQL実行 Statement stmt = con.createStatement (); String sql = "INSERT INTO AnsSheet (問題, a, b, c, d, e, f) VALUES("; sql = sql + "'" + toUnicode(request.getParameter("問題")) + "',"; sql = sql + "'" + toUnicode(request.getParameter("a")) + "',"; sql = sql + "'" + toUnicode(request.getParameter("b")) + "',"; sql = sql + "'" + toUnicode(request.getParameter("c")) + "',"; sql = sql + "'" + toUnicode(request.getParameter("d")) + "',"; sql = sql + "'" + toUnicode(request.getParameter("e")) + "',"; sql = sql + toUnicode(request.getParameter("f")) + ")"; int cnt = stmt.executeUpdate(sql); //接続解除 stmt.close(); con.close(); %> <jsp:forward page="keepAnsSheet.jsp" />

  • JDBCで配列を使ったSQL文(INSERT)

    早速ですがお願いします。例えば下のプログラムでのSQL文なのですが、配列str1[0]の中身”みかん”をINSERTしたいのですが、やりかたがわかりません。プログラミングの素人なので簡単な質問で申し訳ないですけど、どなたか教えてくれないでしょうか? ちなみにこのプログラムでstr1[0]のところを直接みかんと入れたらデータベースに追加することはできました。 import java.sql.*; class jdbc{ public static void main(String args[]){ String[] str1 = new String[1]; str1[0] = "みかん"; try{ Class.forName("org.postgresql.Driver"); String url = "jdbc:postgresql:test"; String user = ""; String password = ""; System.out.println("URL :" + url); System.out.println("USER :" + user); System.out.println("PASSWORD :" + password); Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); int insertCount = stmt.executeUpdate("INSERT INTO shinamono (hinmei,nedan) VALUES ('+str1[0]+', 1500)"); if (insertCount >0){ System.out.println("追加しました"); }else{ System.out.println("追加できませんでした"); } conn.commit(); stmt.close(); conn.close(); }catch(SQLException e){ e.printStackTrace(); }catch(Exception e){ e.printStackTrace(); } } } なおエラーメッセージは次の通りです。 java.sql.SQLException: ERROR: column "みかん" does not exist at org.postgresql.Connection.ExecSQL(Connection.java:533) at org.postgresql.jdbc2.Statement.execute(Statement.java:294) at org.postgresql.jdbc2.Statement.executeUpdate(Statement.java:78) at jdbc.main(jdbc.java:21)

  • javaのMySQL(DataSource)

    ちょっとDataSourceを使って会員登録をしてたら、エラーが出て先に進めなくなってしまったのでご教授願いたいと思い質問させていただきました。 server.xmlに、 <Resource name="MySQL_JDBC" auth="Container" type="javax.sql.DataSource"/> <ResourceParams name="MySQL_JDBC">を書いて、 web.xmlに、 <resource-ref> <res-ref-name>MySQL_JDBC</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref>を書いて、 会員登録をするアクションに、 DataSource dataSource=null; public void init()throws ServletException{ try{ Context context=new InitialContext(); dataSource=(DataSource)context.lookup("java:comp/env/MySQL_JDBC"); }catch(NamingException e){ throw new ServletException(e); } } Connection conn; try{ conn=dataSource.getConnection(); Statement stmt = null; String sql="insert into member(member_id,member_pass,family_name,first_name,birth_year,birth_month,birth_day,address,post_code,mail,"+ "sex,home_tel,job) values('"+ member_id +"',"+ mempasslong +",'"+ family_name +"','"+ first_name +"',"+ birth_year +","+ birth_month +","+ birth_day +",'"+ address +"',"+ post_code +",'"+ mail +"',"+sexint+","+ home_tel +",'"+ job +")"; int result=stmt.executeUpdate(sql); }catch(SQLException e){ message = "登録失敗しました。"; request.setAttribute("message", message); return mapping.findForward("registererror"); } message = "登録完了しました。"; request.setAttribute("message", message); return mapping.findForward("success"); } }と書いて会員登録を完了させたいんですけど、会員情報を入力して実行すると、 致命的: サーブレット action のServlet.service()が例外を投げました java.lang.NullPointerException at memregister.AddressAction.execute(AddressAction.java:100) at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:431) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:236) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1196) というエラーがでて先に進めなくなりました。エラーの場所は分かるのですが、どのように訂正すればいいと思いますか?ちなみにエラー1行目のAddressAction.java:100は、conn=dataSource.getConnection();の箇所です。

    • ベストアンサー
    • Java
  • jspとsqlの連結したページ

    <%@ page import="java.sql.*" %> <% //パラメータの取得 String keyword = request.getParameter("keyword"); //ドライバーのロード Class.forName("com.mysql.jdbc.Driver"); //DBに接続 String url = "jdbc:mysql://localhost/java4z?useUnicode=true&characterEncoding=MS932"; String user = "root"; String pass = ""; Connection con = DriverManager.getConnection(url,user,pass); //SQL発行先ほど指定したConnection con を利用 Statement stmt = con.createStatement(); String sql = "select * from shop where name like '%" + keyword + "%' or author like '%" + keyword + "%' ; ResultSet rs = stmt.executeQuery(sql);%> jspとmysqlの連動したページを作っているのですが select count(*) from テーブル名;を使い 件数を表示(XX件目など)させたいのです さらに値段からXX円以上からXX円以下なども データから検索し表示させたいのですが String sql = "select * from shop where name like '%" + keyword + "%' or author like '%" + keyword + "%' ;の部分をどのように記述すればよいか 解かりません! どなたかお願いします☆()

    • ベストアンサー
    • MySQL
  • ラジオボタンを使って更新 eclipse Tomcat mysql

    ラジオボタンを使って更新するときにデータがnullになってしまう。 更新するときデータが表示状態でデータを買えて更新したい kousin1.java import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import java.sql.*; public class kousin1 extends HttpServlet{ public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException{ doPost(request,response); } public void doPost PrintWriter out = response.getWriter(); String url = "jdbc:mysql://localhost:3306/aiue"; String user = "root"; //ユーザ名 String pass =""; //パスワード String id1 =""; String name1=""; String address1=""; Connection con = null; //データベースへの接続を行なう Statement smt = null; //SQL実行の仲介者 int syutoku = 0; ResultSet rs = null; String id = request.getParameter("id"); String name = request.getParameter("name"); String address = request.getParameter("address"); String radio = request.getParameter("radio"); try{ Class.forName("com.mysql.jdbc.Driver").newInstance(); con = DriverManager.getConnection(url,user,pass); smt = con.createStatement(); System.out.println("更新"); String sql1 = "UPDATE System.out.println(sql1); smt.executeUpdate(sql1); smt.close(); }catch(SQLException e){ throw new ServletException(e); }catch(Exception e){ e.printStackTrace(); }finally{ if(smt != null){ try{smt.close();}catch(SQLException ignore){} } if(con != null){ try{con.close();}catch(SQLException ignore){} } kousin1.jspへ kousin.jsp <html> <head> </head> <form method="POST" action="kousin1"> <body> <div>コード:<input type="text" name="id" value="<%=request.getAttribute("id")%>" size=40></div> <div>名称:<input type="text" name="name" value="<%=request.getAttribute("name")%>" size=42></div> <div>住所:<input type="text" name="address" value="<%=request.getAttribute("address")%>" size=42></div> <div><input type="hidden" name="syutoku" value="<%=request.getAttribute("syutoku")%>" size=40></div> <input type="submit" value="更新"> </form> </body> </html>

  • サーブレットとMysqlについて

    画面のtextboxからDB(Mysql)にinsertするときの質問です。 皆さんのおかげでinsertすることができました。 しかし、textboxが一個で値も一つなのに、 insertするとDBには2行同じ値がinsertされます。 下記のソースのどこがいけないのでしょうか? ご教示をお願いします。 「ソース」 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String[] name10 = request.getParameterValues("sonota"); for (int i = 0; i < name10.length; i++) { System.out.println(i + " " + name10[i]); name10[i] = new String(name10[i].getBytes("8859_1"), "UTF-8"); } Connection conn = null; CallableStatement cs = null; PreparedStatement stmt = null; ResultSet rs = null; String url = "jdbc:mysql://localhost/Sample_db"; String dbUser = "root"; String dbPass = "taratara"; try{ Class.forName("com.mysql.jdbc.Driver").newInstance(); conn = DriverManager.getConnection(url, dbUser, dbPass); String sql= "insert into Sample_table (name) values (?)"; stmt = conn.prepareStatement(sql); for (String n : name10) { stmt.setString(1, n); stmt.executeUpdate(); } int cnt = stmt.executeUpdate(); stmt.close(); RequestDispatcher dispatcher = request.getRequestDispatcher("index.jsp"); dispatcher.forward(request, response); }catch(Exception e){ } } }