我通常知道如何使用preparedStatements来阻止它,但现在我有这样一种方法来建立查询。例如在Java中:
private String buildQuery(String where) {
String query = "SELECT id, name FROM someTable";
if(where.length() > 0) {
query = query + " WHERE " + where;
}
return query;
}
'where'字符串就像这个'variable = value'。我怎么能在这里阻止它?我想分别传递变量和值,使用它们创建预处理语句,然后以某种方式将该预准备语句作为字符串返回,但我不确定。
答案 0 :(得分:1)
这不是特定于任何一个DB API。
TL; DR:不要传递" SQL片段"周围。
不是将select语句或(子)表达式中的complete子句传递给select子句,而是传递组件,使用户数据与标识符分开。
在这种情况下,请不要传递name = value
,单独传递它们。然后验证name
是表的有效列,并为value
部分生成参数。
因此,伪代码(我的Java生锈):
function BuildCommand(string column, object value) {
if !IsValidColumn("theTable", column)) throw InvalidOperation(...)
string sql = "Select column from theTable where " + column + " = @p0";
SqlCommand cmd = new SqlCommand(sql);
cmd.Parameters.Add("@p0", value);
return cmd;
}
答案 1 :(得分:0)
您可以使用地图传递您的值并构建preparedStatement。检查下面的代码它应该类似于那个逻辑
public static PreparedStatement buildQuery(String where,Map<Integer, String> cond)
throws SQLException {
PreparedStatement stat = null;
String query = "SELECT id, name FROM someTable " + where;
try {
stat = con.prepareStatement(query);
for (Map.Entry<Integer, String> e : cond.entrySet()) {
stat.setString(e.getKey(), e.getValue());
}
} catch (SQLException e ) {
// Handle ex
} finally {
}
return stat;
}
public static void main(String[] a) throws SQLException {
Map<Integer,String> cond =new HashMap<Integer, String>();
cond.put(1,"val22");
cond.put(2,"val2");
buildQuery("col1 = ? and col2= ?", cond);
}
答案 2 :(得分:0)
我的建议是,如果参数中有where子句数组,则将函数重写为:
private String buildQuery(String[] where) {
String query = "SELECT id, name FROM someTable";
query = query + " WHERE "
for(int i = 0; i < where.length; i++) {
if(i > 0){
query = query + " AND "
}
query = query + w + " = ?";
}
return query;
}