因此,在where子句参数
中使用时,始终使用PreparedStatement来避免注入select * from user where id = ? and group = ?
我需要将列设置为在运行时选择
select ? from user where id = ? and group = ?
甚至where子句
中的列名select ? from user where ? = ?
但PreparedStatement
不支持此功能。还有谁支持这个?
更新
我的用例:我有一个通用的REST API到(ny)数据库。 用户可以请求
http://server/g/db100/users/300/phone
那被翻译成
select phone from users where id = 300
phone
可以是任何其他列名称(如果列不存在,则服务器响应404等)。所以我没有动态生成查询,并想在自己做之前知道是否有一个lib。
答案 0 :(得分:1)
你不能做那个预备语句的占位符是列值而不是表名。
使用String-concatenation,如
String tablename="xyz";
String query= "select "+tablename+" from user where id = ? and group = ?";
答案 1 :(得分:0)
这样的事情应该适用于您的目的(为博客构建动态查询的示例):
$DB = new PDO('mysql:host='.DBHOST.';port='.DBPORT.';dbname='.DBNAME, DBUSER, DBPASSWORD);
if (!$DB) {
throw new Exception('Could not connect to database');
}
$sql = '';
$select = array(); //which fields to select
$join = array(); //any additional tables to join
$where = array(); //'where' clause
$params = array(); //parameters to add to PDO
//regardless of parameters, select the id
array_push($select, "posts.id");
array_push($join, "blog_posts posts");
array_push($where, "1=1");
array_push($where, "published_date <= NOW()");
//some sort of dynamic query - if we're specifying a search to filter by
if (isset($search) && $search !== '') {
$searchparts = explode(' ', $search);
$searchsql = array();
foreach($searchparts as $key=>$value) {
array_push($searchsql, "(posts.title LIKE ? OR posts.content LIKE ?)");
array_push($params, '%'.$value.'%');
array_push($params, '%'.$value.'%');
}
array_push($where, '('.implode(' OR ', $searchsql).')');
}
//generate SQL query
$sql .= 'SELECT '.implode(', ', $select).' FROM '.implode(' LEFT JOIN ', $join).' WHERE '.implode(' AND ', $where) . ' ORDER BY published DESC';
$prepared = $DB->prepare($sql);
$list = $prepared->execute($params);
if ($list) {
while ($row = $prepared->fetch(PDO::FETCH_ASSOC)) {
//do something with the data
}
}
另一种选择是将列名称(Java)基本列入白名单:
if (column.equals("phone")) {
sql += "phone";
} else if (column.equals("computer")) {
sql += "computer";
}
这样你实际上并没有接受用户输入(虽然它实际上并不重要,因为你已经确认column
正好是“phone
”),并且只是在构建SQL时某些条件,而不仅仅是任何输入。