简体   繁体   中英

SQL Concat Where Clause

What is the better solution of this.

I have a function contain three optional parameters (businessunit_id,department_id,jobtitle). I have to build dynamic WHERE SQL clause according to receiving parameter.

CODE

public function getEmpSearchResult($businessunit_id,$department_id,$jobtitle)
{   
    $i=0;
    $WHERE = "";
    if (!empty($businessunit_id)) 
        {
            if($i==1)  {
                $WHERE = $WHERE." AND";
            }
           $WHERE = "businessunit_id"."=".$businessunit_id;
           $i=1;
        }

    if (!empty($department_id)) 
        {  if($i==1)  {
                $WHERE = $WHERE." AND";
            }
           $WHERE = $WHERE." department_id"."=".$department_id;
           $i=1;
        }

    if (!empty($jobtitle)) 
        { 
            if($i==1)  {
                $WHERE = $WHERE." AND";
            }  
           $WHERE = $WHERE." jobtitle_id"."=".$jobtitle;
           $i=1;
        }

    $query = "SELECT *  FROM `main_employees_summary` WHERE $WHERE ";
    $data = $db->query($query)->fetchAll();
    return $data;  

In above code. To built WHERE condition I am concating $WHERE variable and using $i variable to track AND condition where required.

Is there is any optimized way to achieve this?

Is there is any optimized way to achieve this?

I'm interpreting that as "easier to maintain, easier to read" rather than "performance optimised" - based on the context of your wider question.

This kind of code is 80% of the reason I encourage fellow programmers to look at using database abstraction libraries. The cost in performance rarely outruns the benefit in code cleanliness.

It doesn't look like you're already using a PHP framework, so I'm guessing you may not already be using composer . I'd recommend looking at introducing it to your project, then using that to introduce data abstraction like doctrine or eloquent .

You'll find plenty of assistance on SO for using these libraries and tools.

doctrine brings you dbal , a library which sits between doctrine itself and PDO .

If dbal (or a higher-level library) is utilised, you begin to stop thinking about SQL (and injection protection etc) and start thinking about describing what you want from the database in readable PHP code.

For example: using their object-orientated interface, building extensive where clauses becomes a maintainable breeze ( warning : code written from past memory, may not be literally correct):

$queryBuilder
    ->select('id', 'name')
    ->from('main_employees_summary');

if ($x) {
    $queryBuilder
        ->andWhere('businessunit_id = ?')
        ->setParameter(0, $businessunit_id);
}

if ($y) {
    $queryBuilder
        ->andWhere('department_id = ?')
        ->setParameter(0, $department_id);
}

// ... etc

we can avoid the use $i as follows:

$WHERE = "";
if (!empty($businessunit_id))
{
   $WHERE .= "businessunit_id='{$businessunit_id}' AND ";
}

if (!empty($department_id))
{
    $WHERE .= "department_id='{$department_id}' AND ";
}

if (!empty($jobtitle))
{
    $WHERE .= "jobtitle_id='{$jobtitle}' AND ";
}
if ($WHERE) {
    $WHERE = preg_replace('/AND\s$/', '', $WHERE);//removing the last 'AND '
    $query = "SELECT *  FROM `main_employees_summary` WHERE $WHERE ";
    $data  = $db->query($query)->fetchAll();
}
return $data;

Or using array

$whereArr = array();
if (!empty($businessunit_id))
{
   $whereArr[] = "businessunit_id='{$businessunit_id}'";
}
//.......
if (!empty($whereArr)) {
    $WHERE = implode(' AND ', $whereArr);//joining with ' AND '
    $query = "SELECT *  FROM `main_employees_summary` WHERE $WHERE ";
    //.....
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM