我需要从一个表中获取数据,该表有多个过滤器并限制来自java脚本数据表请求的行
SELECT coalesce(parent_id,siteid) as siteid, address, state, status, plan,
remarks, FROM archive LEFT OUTER JOIN site_mappings ON
site_dn = mrbts AND siteid = child_site_id
在我的代码中,我有一个实现在执行预准备语句之前在查询中附加过滤器。
此处的过滤条件为List<String[]> filters
,其过滤器值为列表名称(UPPER(mrbts)类似于UPPER(&#39;%6105%&#39;)) ... 6105是filter string和mrbts是列名
private String createFilterWhereClause(List<String[]> filters) {
StringBuilder sb = new StringBuilder();
Iterator<String[]> filterParmItr = filters.iterator();
while (filterParmItr.hasNext()) {
String[] filterParm = filterParmItr.next();
sb.append("(")
.append(filterParm[ScFilterCriteria.FILTER_PARM_VAL])
.append(")");
if (filterParmItr.hasNext()) {
sb.append(" and ");
}
}
return sb.toString();
}
在执行期间,它会形成如下的sql查询,并在预准备语句中执行。
SELECT coalesce(parent_id,siteid) as siteid, address, state, status, plan,
remarks, FROM archive LEFT OUTER JOIN site_mappings ON site_dn = mrbts AND
siteid = child_site_id where UPPER(mrbts) like UPPER('%4105%') and
((UPPER(technology) like UPPER('%LTE%')))
它具有SQL注入漏洞。为了解决这个问题,我试图通过使用预备语句集字符串来保护它,如下所示
SELECT coalesce(parent_id,siteid) as siteid, address, state, status, plan,
remarks, FROM archive LEFT OUTER JOIN site_mappings ON site_dn = mrbts AND
siteid = child_site_id where ?
使用预备声明,
PreparedStatement ps = null;
Connection connection = null;
ps = connection.prepareStatement(sql);
String filters = createFilterWhereClause(filterClause);
ps.setString(1, filters );
在设置字符串
之后用单引号形成的sql查询中的问题SELECT coalesce(parent_id,siteid) as siteid, address, state, status, plan,
remarks, FROM archive LEFT OUTER JOIN site_mappings ON site_dn = mrbts AND
siteid = child_site_id where '((UPPER(mrbts) like UPPER(\'%6105%\')))';
如何在设置字符串和/或任何其他方法中删除单引号? 你能帮助我吗?
答案 0 :(得分:2)
将您的查询更改为:
SELECT coalesce(parent_id,siteid) as siteid, address, state, status, plan,
remarks, FROM archive LEFT OUTER JOIN site_mappings ON site_dn = mrbts AND
siteid = child_site_id where ((UPPER(mrbts) like UPPER(?));
仅使用预准备的语句参数设置参数。
添加动态条件: //你的基本sql语句 String sqlString =&#34;选择......&#34 ;;
//add condition only in few cases
if(mycondition){
sqlString += "WHERE mycondition = ?"
}
ps = connection.prepareStatement(sql);
//bind the corresponding dynamic parameter you just added in the where clause.
if(mycondition){
ps.setString(1, myparameter );
}
如果没有任何用户输入与sqlString连接,那么这样做是安全的。
答案 1 :(得分:2)
静态SQL语句的代码如下所示:
String query = "SELECT coalesce(parent_id,siteid) AS siteid, address, state, status, "
+ "plan, remarks "
+ "FROM archive "
+ "LEFT OUTER JOIN site_mappings ON site_dn = mrbts "
+ "AND siteid = child_site_id "
+ "WHERE UPPER(mrbts) LIKE UPPER(?) "
+ "AND UPPER(technology) LIKE UPPER(?)";
// UPPER probably is not needed; there was one spurious comma after "remarks"
String mrbts = "4105";
String technology = "LTE";
try (PreparedStatement preparedStatement = connection.prepareStatement(query)) {
preparedStatement.setString(1, "%" + mrbts + "%");
preparedStatement.setString(2, "%" + technology + "%");
try (resultSet = preparedStatement.executeQuery()) {
while (resultSet.next()) {
...
}
return list; // Or such
}
}
对于动态数量的标准:
StringBuilder sb = new StringBuilder();
List<Object> params = new LinkedList<>();
...
sb.append(" AND mrbts LIKE ? ");
params.add(mrbts);
...
int column = 1;
for (Object param : params) {
preparedStatement.setObject(column, param);
++column;
}
答案 2 :(得分:0)
正如Joop Eggen所说,使用准备好的陈述