【发布时间】:2016-10-24 12:51:02
【问题描述】:
因此,这更多是为了获得您对最佳方法的意见。
我有一个我认为非常优雅的方法来构建一个带有直接 WHERE 子句的简单动态 SQL 语句。 WHERE 子句可以包含多个字段,但它是有限的,因为它不允许 不同的 运算符(比较或逻辑)。
我可以用这个构建以下内容:
SELECT * from table_name WHERE field_1 = "value_1" AND field_2 = "value_2";
//or I can do
SELECT * from table_name WHERE field_1 = "value_1" OR field_2 = "value_2";
//or I can do
SELECT * from table_name WHERE field_1 <> "value_1" AND field_2 <> "value_2";
我可以不构建以下内容:
SELECT * from table_name WHERE field_1 = "value_1" AND field_2 <> "value_2";
//nor can I do
SELECT * from table_name WHERE field_1 = "value_1" AND field_2="value_2" OR field_3 = "value_3
使用数字和日期时,当我想查找值介于两者之间的记录时,这成为一个真正的问题,我需要用两个不同的值将同一个字段传递两次......不是吗?
SELECT * from table_name WHERE price BETWEEN 10 AND 20;
SELECT * from table_name WHERE date BETWEEN "2016-08-01" AND "2016-08-15";
不要忘记带有“IN”或 LIKE 语句的多个条件,这也不会建立,即:
SELECT * from table_name WHERE field_1 IN("value_1","value_2, "value_3");
SELECT * from table_name WHERE field_1 LIKE "val%";
这是我当前的代码:
// db contains my DB connection
$db = new DB();
$where = 'WHERE';
$criteria = array();
foreach ($_GET as $key => $value) {
$where = $where.' '.$key.'=? AND';
array_push($criteria,$value);
}
if(count($_GET) > 0){
// $sql will look like: SELECT * FROM table_name WHERE field_1 = ? AND field_2 = ?
// $criteria is an array of values to pair with the above prepared statement.
// Will look like: $criteria("value_1", "value_2")
$sql = 'SELECT * FROM mcl_data_gap '.$where;
$results = $db->query($sql,$criteria);
} else {
$sql = 'SELECT * FROM mcl_data_gap';
$results = $db->query($sql);
}
// .... continue on using above SQL statement
在上面的代码中我使用了 get 但我的假设是 post 也可以。
我想出的唯一想法是插入更多键值对,其中包含编码格式所需的运算符,这样我就可以查找这些运算符并基于它们构建语句,但我只是觉得那里是一种更好的方法,我希望你能提供帮助。
我刚刚想到的另一个选择是在将 SQL 传递给服务器并执行它之前构建它。
或者我可以发布包含整个 WHERE 语句的对象吗?
【问题讨论】:
-
您的代码易受 SQL 注入攻击。 永远不要相信用户输入,即使是变量名也不行。我不得不尝试一次,因为 PHP 会自动用下划线替换空格,但它不会替换制表符,但是,mysql 接受为空格。因此,试图查询
yourfile.php?%27;DROP%09TABLE%09SomeImportantTable;%09--=a的不友好的人将成功积极精简您的数据库。 -
SQL 注入在这里是个问题。用户可以将
$key的值设为任何值,并给您带来很多问题。您仍然可以构建动态查询,但您应该输入所有 SQL 并使用$_GET参数来确定最终查询中使用了哪些 SQL。 -
SQL 字符串和参数被传递给一个类,该类使用 PDO 准备语句来查询我的数据库。我的理解是 PDO 准备好的语句用于防止 SQL 注入。