2

SQL インジェクション攻撃を防ぐために、プロジェクト内のすべての SQL ステートメント コードをパラメーター化クエリに変換する必要があります。しかし、クエリ条件に「IN」ケースが含まれていると問題が発生しました。このように (DB2 データベースを使用):

String employeeId = 'D2309';
String name = "%brady%";

List<Integer> userRights = new ArrayList<Integer>();
userRights.add(1);
userRights.add(2);
userRights.add(3);

String sql = "SELECT * FROM T_EMPLOYEE WHERE EMPLOYEE_ID = ? AND NAME LIKE ? 
AND RIGHT IN (?)";

jdbcTemplate.query(sql, new Object[] {employeeId, name, userRights}, new 
EmployeeRowMapper());

上記のコードの実行は、次の例外で失敗しました。

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad 
SQL grammar [SELECT * FROM T_EMPLOYEE WHERE EMPLOYEE_ID = ? AND NAME LIKE ? AND 
RIGHT IN (?)]; nested exception is com.ibm.db2.jcc.am.io: [jcc][1091][10824]
[3.57.82] .... ERRORCODE=-4461, SQLSTATE=42815

ここでの質問は、JdbcTemplate が IN ケースのパラメーター化されたクエリをサポートしていないということですか? そして、この作業は NamedParameterJdbcTemplate で実行できることを知っています。また、NamedParameterJdbcTemplate のみが IN ケース クエリを実行できるかどうかを知っていますか?

どうもありがとう。

4

1 に答える 1

0

コメントで既に述べたように、このソリューションは多数の SQL ステートメントを動的に生成するため、満足できません。の数がuserRights1 ~ n の場合、キャッシュ内に最大 n 個のプリペアド ステートメントが必要です。

以下はうまくいくはずです(私は試していません)。

String employeeId = 'D2309';
String name = "%brady%";

List<Integer> userRights = new ArrayList<Integer>();
userRights.add(1);
userRights.add(2);
userRights.add(3);

// build the input string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < userRights.size; i++) {
    sb.append("?");
    if (i < userRights.size() - 1) {
        sb.append(", ");
    }
}

// build the SQL
String sql = "SELECT * FROM T_EMPLOYEE WHERE EMPLOYEE_ID = ?" +
    " AND NAME LIKE ?" +
    " AND RIGHT IN (" + sb.toString() + ")";

// init the object array
// size is employeeId + name + right
Object[] param = new Object[2 + userRights.size()];

// fill it
param[0] = employeeId;
param[1] = name;

for (int i = 0; i < userRights.size(); i++) {
    param[i + 2] = userRights.get(i);
}

jdbcTemplate.query(sql, param, new EmployeeRowMapper());
于 2012-11-02T06:59:36.997 に答える