0

私のページに次のようなセクションがたくさんあると想像してください ( example page ):

  <div class="content">
    </div>

私の目標は、ページ全体を MySQL DB エントリにスクレイピングすることです。私は現在これを次のように行っています:

        //Declare SQL statement
    String sql = "INSERT into rns " + 
            "(rns_pub_date, rns_headline, rns_link, rns_fulltext, constituent_id) values (\""+
            rns.getRnsPubDate() + "\",\"" +
            rns.getRnsHeadline() + "\",\"" +
            rns.getRnsLink() + "\",\"" +
            rns.getRnsFullText() + "\",\"" +
            "(select constituent_id from constituent where constituent_name = " + rns.getRnsConstituentName() + "\")";



    //SQL Statement Debug
    Log.d(CLASS_NAME, "createRns. sqlStatement: " + sql);


    //Initialize insertValues
    insertValues = connect.prepareStatement(sql);

ただし、ページ内に「」マークが複数あるため、これは失敗します。

いくつかのオプションが表示されます:

  1. 次のように文字をエスケープします: ' \" '
  2. 文字を次のように置き換えます: ' " '
  3. 関係のないデータ (HTML) をすべて削除し、関係のあるデータのみを DB に保存します。

SQL インジェクションの防止に関してもベスト プラクティスがあることを認識しています。ただし、これはスタンドアロン システムであるため、現時点では問題ありません。それを防ぐ方法を説明できる答えがあれば、代わりにそれを実装することをお勧めします。

編集 1: @chrylis のコメントに続きます。これは私が持っているものです:

    //Insert values into variables
    String rns_pub_date = rns.getRnsPubDate();
    String rns_headline = rns.getRnsHeadline();
    String rns_link = rns.getRnsLink();
    String rns_fulltext = rns.getRnsFullText();
    String rns_constituent_name = rns.getRnsConstituentName();

    //Prepare the SQL string
    String sql = "INSERT into rns (rns_pub_date, rns_headline, rns_link, rns_fulltext,constituent_id) VALUES" + "(?,?,?,?,(select constituent_id from constituent where constituent_name = \"" + rns.getRnsConstituentName() + "\")";

    //Prepare the statement
    PreparedStatement prest = connect.prepareStatement(sql);
    prest.setString(1, rns_pub_date);
    prest.setString(2, rns_headline);
    prest.setString(3, rns_link);
    prest.setString(4, rns_fulltext);
    prest.setString(5, rns_constituent_name);

ただし、次のエラーが発生します。

Parameter index out of range (5 > number of parameters, which is 4).

編集2:

挿入は、5 番目のパラメーターのエスケープされた二重引用符を削除することで修正されました。

String sql = "INSERT into rns (rns_pub_date, rns_headline, rns_link, rns_fulltext, constituent_id) VALUES" + "(?,?,?,?,(select constituent_id from constituent where constituent_name = ?))";
4

2 に答える 2

2

PreparedStatement を使用します。エスケープする必要はありません。使用例はAPIで

于 2013-09-22T07:49:50.320 に答える
2

これは、SQL インジェクションのために悪い習慣であるだけでなく、遅くて非効率的であり、引用符の問題もあります。パラメータ化されたクエリを使用します。

于 2013-09-22T07:50:00.170 に答える