Build dynamic SQL with “AND” expressions without confusing nested conditionals?

二次信任 提交于 2020-01-01 16:52:48

问题


I'm fairly new to php and coding in general.

I have a series of conditions I need to test if they are set. They are $option1, $option2, $option3

if (isset($option1)){
    if (isset($option2)){
        if (isset($option3)){
            $query = "SELECT *
                               FROM Group
                               WHERE FirstOption = '$option1' AND SecondOption = '$option2' AND ThirdOption = '$option3'";
        }
        else {
            $query = "SELECT *
                               FROM Group
                               WHERE FirstOption = '$option1' AND SecondOption = '$option2";
        }
    }
    else {
        $query = "SELECT *
                           FROM Group
                           WHERE FirstOption = '$option1' AND ThirdOption = '$option3";
    }
}
else {
    // .. snip, much more duplicated code ..
}

So the issue here is I need unique queries for mysql based upon whether the conditions are set or not. But they are within each other a great deal and I actually have 7 lots of options, so the branching is absolutely massive! I stopped at three after nearly confusing myself.

There has to be a far superior way of writing this - could anybody help me understand better?


回答1:


No dynamic sql building needed. Just use logic.

SELECT *
  FROM Group
 WHERE (FirstOption = '$option1' or '$option1' = '') 
   AND (SecondOption = '$option2' or '$option2' = '')
   AND (ThirdOption = '$option3' or '$option3' = '')

Ideally you would use placeholders and prepared statements, but the above is most clear for instructional purposes.

In case anyone is curious - there's no significant query overhead to this. Any modern database engine will optimize the '$option1' = '' expression into a constant value, evaluating it to boolean only once.




回答2:


My ordinary way:

$cond=array();
$bind=array();
if(isset($option1))
{
    $cond[]="FirstOption=?";
    $bind[]=$option1;
}
if(isset($option2))
{
    $cond[]="SecondOption=?";
    $bind[]=$option2;
}
if(isset($option3))
{
    $cond[]="ThirdOption=?";
    $bind[]=$option3;
}
$sql="SELECT * FROM `group`";
if(count($cond)>0) $sql.=" WHERE ".implode(" AND ",$cond);
$stmt=$mysqli->prepare($sql);
if(count($bind)>0)
{
    foreach($bind as $idx=>$val)
    {
        $stmt->bind_param("s",$bind[$idx]);
    }
}



回答3:


$baseSQL = "SELECT * FROM Group";

if(isset($option1)){
    sprintf("%s world. Day number %u",$str,$number);
    $whereSQL[] = sprintf("FirstOption = '%s'",mysqli_real_escape_string($mysqli,$option1));
}
if(isset($option2)){
    $whereSQL[] = sprintf("SecondOption = '%s'",mysqli_real_escape_string($mysqli,$option2));
}
if(isset($option3)){
    $whereSQL[] = sprintf("ThirdOption = '%s'",mysqli_real_escape_string($mysqli,$option3));
}

if(isset($whereSQL)){
    $query = $baseSQL ." WHERE " . implode(" AND ",$whereSQL);
}



回答4:


Try this

$sql = "Select * from Group where 1=1 ";
$whr = "";

if(isset($option1)){
$whr .= " and FirstOption = $option1";
}
if(isset($option2)){
$whr .= " and SecondOption = $option2";
}
if(isset($option3)){
$whr .= " and ThirdOption = $option3";
}
// nth element ...

if(isset($optionN)){
$whr .= " and nTHOption = $optionN";
}

$sql .= $whr;

This way you can add any numbers of options to your query in where condition.




回答5:


if(isset($option1)||isset($option2)||isset($option3)){
$sqlToAdd = (isset($option1)?" FirstOption=$option1":"");
$sqlToAdd .= ($sqlToAdd==""?"":" AND ").(isset($option2)?" SecondOption=$option2":"");
$sqlToAdd .= ($sqlToAdd==""?"":" AND ").(isset($option3)?" ThirdOption=$option3":"");
$sql = "SELECT *
                               FROM Group
                               WHERE $sqlToAdd";
}


来源:https://stackoverflow.com/questions/14351617/build-dynamic-sql-with-and-expressions-without-confusing-nested-conditionals

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!