sql >> データベース >  >> RDS >> Mysql

プリペアドステートメントを使用した動的列名+'sを含む変数を使用したSQLクエリ

    右。バインドパラメータとして識別子を指定することはできません。列の名前はSQLテキストの一部である必要があります。

    次のように、列の名前をSQLテキストに動的に組み込むことができます。

      sql = "UPDATE diseaseinfo"
          + " SET `" + colname + "` = ?"
          + " WHERE companyname = 'mycom' AND diseaseName = ?";
    

    そして、残りの2つのバインドパラメータの値を指定します

      preparedStmt.setString(1, attrData);
      preparedStmt.setString(2, medname);
    

    そして、あなたはSQLインジェクションについて心配することについて絶対に正しいです。

    バインド値として提供され、attrDataの値を一重引用符で囲みます およびmedname SQLインジェクションに関しては、問題にはなりません。

    しかし、私が提供した例は colnameを組み込むことで脆弱になります colnameが保証されていない場合は、SQLテキストに変数を追加します ステートメントに含めるのは「安全」です。

    したがって、colnameに値を割り当てる必要があります 「安全」。

    私たちが使用できるいくつかのアプローチはそれを行います。最も安全なのは「ホワイトリスト」アプローチです。このコードは、特定の許可された「安全な」値のみがcolnameに割り当てられるようにすることができます。 、colnameの前 SQLテキストに含まれます。

    簡単な例として:

      String colname;
      if (attributes.equals("someexpectedvalue") {
          colname = "columnname_to_be_used";
      } else if (attributes.equals("someothervalid") {
          colname = "valid_columname";
      } else {
         // unexpected/unsupported attributes value so
         // handle condition or throw an exception 
      }
    

    より柔軟なアプローチは、バックティック文字がcolnameに表示されないようにすることです。 。この例では、colnameの値 エスケープされています バックティックで囲むことによって。したがって、バックティック文字がcolnameに表示されない限り 、指定された値が識別子以外のものとして解釈されないようにします。

    ハードコードされたバックティック文字を使用するためのより一般的な(そして複雑な)アプローチについては、supportsQuotedIdentifiersを使用することを検討できます。 およびgetIdentifierQuoteString java.sql.DatabaseMetaDataのメソッド クラス。

    (OPコードでは、attributesのコンテンツのデータ型は表示されません 。 replaceという名前のメソッドの呼び出しが表示されます 、およびそれに提供される引数。 attributesを想定 は文字列であり、これは列名であると想定されていますが、文字列に「スペース一重引用符スペース」が含まれる理由、またはそれを削除する必要がある理由はまったくわかりません。この言及を除いて、この回答はそれを扱っていません。)




    1. Oracleのdump(systimestamp)バイトの意味

    2. プロシージャは、提供されなかったパラメータを予期しています

    3. '𠂉'有効なUnicode文字ではありませんが、Unicode文字セットに含まれていますか?

    4. OS XでXAMPPを使用しているときにmysqlコマンドラインツールにアクセスするにはどうすればよいですか?