2016-05-27 10 views
1

SQLデータベースのエントリを検索しようとしていますが、検索バーに一重引用符を入力して実行するとエラーが発生します。特定の名前を入力すると、データベースから正しいエントリが返されます。私は ''を使用してエスケープし、準備されたステートメントを使用することについて読んだが、どちらの答えも私のケースに合っていないか、概念的に何かを理解していない。 (私は初心者です)事前に感謝! :)検索バーで一重引用符を使用する

以下は、私のjspファイルのコード、実行時の外観、そして一重引用符を挿入するとどうなりますか?

<%@page import="java.sql.*"%> 
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> 

<!DOCTYPE html > 
<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> 
<title>List of Entries</title> 
</head> 
<body> 
    <h1>Retrieve Data</h1> 
    <form method="post" action="index.jsp"> 
     Search <input type="text" name="search" 
      placeholder="Enter your search here..." /> 
      <input type="submit" 
      value="Search" name="submit"/> 
    </form><br><br> 
    <% 
     Connection con = null; 
     Statement stmt = null; 
     ResultSet rs = null; 
     ResultSet rs2 = null; 


     try { 
      String searchReq = request.getParameter("search"); 
      try { 
       Class.forName("com.mysql.jdbc.Driver"); 
      } catch (ClassNotFoundException e) { 
       e.printStackTrace(); 
      } 
      //make connection to db 
      con = DriverManager.getConnection(
        "jdbc:mysql://localhost:3306/profile", "root", ""); 

      //create a statement 
      stmt = con.createStatement(); 

      //executes SQL query 
      rs = stmt.executeQuery("SELECT * FROM person WHERE Name LIKE '%"+ searchReq +"%'"); 
    %> 

    <table border="1"> 
     <tr> 
      <td><b>Name</b></td> 
      <td><b>Birthday</b></td> 
      <td><b>Address</b></td> 
      <td><b>Gender</b></td> 
      <td><b>School</b></td> 
     </tr> 

     <% 
      try { 
        while (rs.next()) { 
     %> 

     <tr> 
      <td><%=rs.getString("Name")%></td> 
      <td><%=rs.getString("Birthday")%></td> 
      <td><%=rs.getString("Address")%></td> 
      <td><%=rs.getString("Gender")%></td> 
      <td><%=rs.getString("School")%></td> 
     </tr> 

     <% 
      } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
     %> 

    </table> 
    <% 
     } 

     catch (Exception e) { 
      e.printStackTrace(); 
     } 

     finally { 

      rs.close(); 
      stmt.close(); 
      con.close(); 

     } 
    %> 
</body> 
</html> 

jsp page with search bar

error page

+0

がこれを読んでhttp://stackoverflow.com/a/37479030/1997376 –

+0

文字列を厳しくしないで、パラメータを使用します。また、どのSQLを使用していますか? (SQL-Server、MySQL、Oracle) – Chuck

+0

@チャックMYSQL。申し訳ありませんが、あなたは文字列がよりタイトであることを意味しますか? – episkeyyy

答えて

2

あなたの主な問題はここにある:

"SELECT * FROM person WHERE Name LIKE '%"+ searchReq +"%'" 

変数searchReqでは、SQLクエリを作成している、単一引用符が含まれている場合:

SELECT * FROM person WHERE Name LIKE '%'%' 
            ^sql engine consider this as end of string literal 

データベースはこのクエリを解析しようとすると、それはあなたがしようとした場合、内部"で文字列を宣言したい場合は、これは、純粋なJavaと同じであり、正しい部分SELECT * FROM person WHERE Name LIKE '%'を発見してから1 %'

無効:

String s = "my string with " quote"; 
         ^java considers this as end of string literal 
あなたは、構文エラーメッセージが表示されます、あなたはJavaのためにそれはそう \"

あり、そのようなシンボルをエスケープする必要があります

は、この問題を解決するには、パラメトリッククエリを使用する、またはチェックのいずれかの必要sql standard

<文字表現> :: = < nonquo​​te文字> | <引用記号>

<引用記号> :: = <引用> <引用>

ので、単一引用符は/存在しなければならないが、あなたの場合だけ、''

ので、二重の単一引用符のようにエスケープすべて'''に置き換えてください.SQLインジェクションを取り除き、失敗したクエリを修正します。

最も簡単な方法は、searchReq = searchReq.replaceAll("'", "''");

ですが、SQL演算子LIKEは<エスケープ文字>が指定されていない場合は、各<がPで>文字をアンダースコア%_

2つの追加の特殊記号を持っています任意の文字指定子を表し、それぞれ<パーセント>の文字はPの中の任意の文字列指定子を表し、Pのいずれの文字も<アンダースコア>文字または<パーセント>文字はそれ自身を表します。

ユーザーがこれらのシンボルを入力した場合、あなたのクエリで何が見つかりますか?

ヒント:標準のを見てみましょう:

<述語>のように:: = <マッチ値> [NOT] LIKE <パターン> [ESCAPE <エスケープ文字>]

+0

うわー、徹底的な答えをありがとう! :)しかし、私はまだ情報で何をするか全く分かりません – episkeyyy

+0

@episkeyyy javaについて忘れてみてください。ちょうど異なるSQLクエリを作成してテスト行を作成してください。すべての行ではなく、この行のみを返す-query –

+0

Ok。あなたの時間をありがとう! – episkeyyy

関連する問題