如何在SQL语句中添加QBE过滤器


How to add QBE filters to SQL statement

我很高兴只是在我的网站上添加一个if语句来产生一个数据列表,但现在它在000行代码和它的混乱。

我相信有一个更好的逻辑我正在做的事情,所以任何帮助都会很好。

这是我的逻辑(或它应该如何工作)

check access lvl and add to sql - `accesslvl` = '1' 
Check if get_status is set - if set add to sql
check if get_product is set - if set add to sql
check if get_compnay is set - if set add to sql
check if get_datefrom is set - if set add to sql
check if get_dateto is set - if set add to sql
运行查询

现在我已经使用了很多嵌套的div来确定是否设置了get,如果没有,不要和它们到sql,也必须计算出是否需要一个WHERE或and。

我发现这个帖子动态创建mysql搜索字符串?

我想这可能会有帮助,但不确定。我的代码示例。

if (isset($_GET['product'])&& $_GET['product'] >0){
        $product = $_GET['product'];
        if($a == 1){
            $sql_fields ="WHERE `Status_ID` = '$status' AND `Product` = '$product'";
        }
        else {
                $sql_fields ="WHERE `Product` = '$product'";
        }
        $b++;
    }
if (isset($_GET['company'])&& $_GET['company'] >0){
        $company = $_GET['company'];
        if($a == 0 && $b == 0){
                $sql_fields ="WHERE `Company_ID` = '$company'";
            }
        else if($a == 0 && $b == 1){
            $sql_fields ="WHERE `Product` = '$product' AND `Company_ID` = '$company'";
        }
        else if($a == 1 && $b == 0){
            $sql_fields ="WHERE `Status_ID` = '$status' AND `Company_ID` = '$company'";
        }
        else {
                $sql_fields ="WHERE `Status_ID` = '$status' AND `Product` = '$product' AND `Company_ID` = '$company' ";
        }
        $c++;
    }
if ($a == 0 && $b == 0 && $c == 0){
        $sql_fields =" ";
    }
if (isset($_GET['date_from']) && $_GET['date_from'] >0 && isset($_GET['date_to'])&& $_GET['date_to'] >0){
        if ($access_level == 1){
            if ($a == 0 && $b == 0 && $c == 0){
            $search_date = "WHERE `Date_added` >= '$date_from' AND `Date_added` <= '$date_to'";
            }
            else {
            $search_date = "AND `Date_added` >= '$date_from' AND `Date_added` <= '$date_to'";
            }
    }
if ($access_level ==2 or $access_level ==3){
            if ($a == 0 && $b == 0 && $c == 0){
            $search_date = " `Date_added` >= '$date_from' AND `Date_added` <= '$date_to'";
            $and = "AND";
            }
            else {
            $search_date = " `Date_added` >= '$date_from' AND `Date_added` <= '$date_to'";
            $and = "AND";
            }
        }
    }
else {
        $search_date = "";
        $and = "";
}

这是我修改后的代码!

$fields = array();
if (isset($_GET['status']) && $_GET['status'] >0){
    $status = $_GET['status'];
    $fields['Status_ID']= $_GET['status'];
    }
if (isset($_GET['product']) && $_GET['product'] >0){
    $product = $_GET['product'];
    $fields['Product_ID']= $_GET['product'];
    }
if (isset( $_GET['company']) && $_GET['company'] >0){
    $company = $_GET['company'];
    $fields['Company_ID']= $_GET['company'];
    }
if (isset( $_GET['closer']) && $_GET['closer'] >0){
    $closer = $_GET['closer'];
    $fields['Closer']= $_GET['closer'];
    }
if (isset( $_GET['date_from']) && $_GET['date_from'] >0 && isset( $_GET['date_to']) && $_GET['product'] >0){
    $date_from = $_GET['date_from'];
    $date_from = $_GET['date_to'];
    }
$field_count = count($fields);
if ($field_count == 0){
    $sql = "";
}
else {
    $field_count --;
    $sql="";
    $i=0;
        foreach($fields as $k => $v) {
            if($i==0){
                $sql = "WHERE `$k`  = '$v'";
                }
            else{
            $sql .=" AND `$k`  = '$v'";
            }
    $i++;
    }
}
 echo $sql;

现在我使用了很多嵌套div来计算get是否设置了

混合html, php和sql在一个脚本是一个久经考验的意大利面条代码配方。如果你不想完全分开HTML和PHP至少

  • 把PHP逻辑放在你的脚本和
  • 清理所有给定的输入
  • 构建where条件
  • 查询数据库

,然后只通过在适当的位置输出db结果来呈现HTML部分。不要把上面的任何逻辑放到脚本的HTML部分。

至于你的条件逻辑来构建where子句:我不知道它做什么。我看了它30秒,但代码格式很差,并且有像$a, $b和$c这样的变量和魔术数字。您应该选择具有适当缩进和格式的一致的编码风格。您应该适当地命名变量,并使用常量或函数调用最小化幻数。从长远来看,这将使代码更具可读性。您(和其他开发人员)将能够更容易地理解正在发生的事情。

首先,条件分支不需要确定要使用的正确SQL关键字(只需使用连接关键字作为状态变量)。此外,您的代码容易受到SQL注入的攻击,并可能导致查询不能有效地使用索引。考虑:

$join='WHERE';
$sql_filter='';
// potentially te following field meta data could be stored in a DB or file...
// or even selectively overriden at run time by the request...
$qbe=array(
   array('get_name'=>'product',
         'db_name'=>'Product',
         'op' => '=',
         'type'=>'string'),
   array('get_name'=>'date_from',
         'db_name'=>'date_added',
         'op' => '>=',
         'type' =>'date'),
   array('get_name'=>'date_to',
         'db_name'=>'date_added',
         'op' => '<=',
         'type' =>'date')
   ....
);
foreach ($qbe as $f) {
    $sql_filter=add_filter($sql_filter, $join, $f['get_name'],
      $f['type'], $f['op'], $f['db_name']);
}
function add_filter($sql_filter, &$join, $get_name, $type, $op, $db_name)
{
   $mod_filter=$sql_filter;
   if ($_GET[$get_name]) {
      switch(upper($type)) {
         case 'DATE':
            $mod_filter=$mod_filter 
              . " $join $db_name $op " 
              . date(strtotime($_GET[$get_name]), 'YmdHis');
            break;
         case 'NUMBER':
            $match=array();
            if (preg_match('/([-+]?[0-9]*'.?[0-9]+([eE][-+]?[0-9]+)?)/', $_GET[$get_name], $match) {
              $mod_filter=$mod_filter 
              . " $join $db_name $op " . $match[0];
            }
            break;
         default:
            $mod_filter=$mod_filter . " $join $db_name $op '" .
                mysql_real_escape_string($_GET[$get_name]) . "'";
            break;
      }
      if ($mod_filter != $sql_filter) {
           $join='AND';
      }
      return $mod_filter;
   }