右。バインドパラメータとして識別子を指定することはできません。列の名前は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
を想定 は文字列であり、これは列名であると想定されていますが、文字列に「スペース一重引用符スペース」が含まれる理由、またはそれを削除する必要がある理由はまったくわかりません。この言及を除いて、この回答はそれを扱っていません。)