Question

I'm having trouble executing my dynamically built query when a bindValue is empty

  • If a bindValue is defined and not used the query returns no results. As long as value is entered for all search fields my query works.
  • I've tried both bindValue and bindParam.
  • The intent is to only query fields that are filled in on the search form.
  • I notice in my local MySQL log that the statement will prepare properly but not execute unless all bindValue search terms are used.

Here is the mysql.log (with all 3 fields filled in):

142 Connect root@localhost on drawings03
142 Prepare SELECT * FROM draw WHERE (`LocationNumber` = ?  && `DrawingNumber` = ?  && `DrawingDate` >= ? )
142 Execute SELECT * FROM draw WHERE (`LocationNumber` = '525'  && `DrawingNumber` = '101'  && `DrawingDate` >= '1950' )
142 Close stmt  
142 Quit

Here is a piece of the php:

<?php
  //grabs variables from a search form
$searchTerms['locnum'] = $_GET['locnum'];
$searchTerms['drawnum'] = $_GET['drawnum'];
$searchTerms['projtitle'] = $_GET['projtitle'];
$searchTerms['shttitle'] = $_GET['shttitle'];
$searchTerms['shtnum'] = $_GET['shtnum'];
$searchTerms['discp'] = $_GET['discp'];
$searchTerms['drawdate'] = $_GET['drawdate'];

//Loops through the array
foreach ($searchTerms as $field => $value) {
   if ($value != null && $value != '' && $value != ' ' ) {
// Based on the key name in the array, decide which 
// SQL statement to add to the array to be constructed
      switch ($field) {
         case 'locnum':
            $where[] = "`LocationNumber` = :locnum ";
            break;
         case 'drawnum':
            $where[] = "`DrawingNumber` = :drawnum ";
            break;
         case 'drawdate':
            $where[] = "`DrawingDate` >= :drawdate ";
            break;         
      }              
   }             
}

// Combine WHERE statements into one with && separating each one
$whereSQL = implode(' && ', $where);  
$stmt = $db->prepare("SELECT * FROM draw WHERE (".$whereSQL.")");
$stmt->bindValue(':locnum', $locnum, PDO::PARAM_INT);
$stmt->bindValue(':drawnum', $drawnum, PDO::PARAM_INT);
$stmt->bindValue(':drawdate', $drawdate, PDO::PARAM_STR);

$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
$row_count = $stmt->rowCount();
echo "<div class='span12'><b>".$row_count." results"."</b><br>Click <b>to sort</b>.  &nbsp; Right-click link and save-as <b>to save a PDF</b>.</div>";
foreach ($rows as $value) {
   echo $value['LocationNumber']." - ".$value['DrawingNumber']." - ".substr($value['DrawingDate'],0,4)."<br>";
}
?>
Was it helpful?

Solution

I was able to solve this problem by only adding $stmt->bindValue for fields that were not empty by adding this:

foreach ($searchTerms as $field => $value) {
    if ($value != null && $value != '' && $value != ' ' ) {
        // Based on the key name in the array, decide which SQL statement to add to the array to be constructed
        switch ($field) {
            case 'locnum':
                            $stmt->bindValue(':locnum', $locnum, PDO::PARAM_INT);
                            break;
            case 'drawnum':
                            $stmt->bindValue(':drawnum', $drawnum, PDO::PARAM_INT);
                            break;
            case 'drawdate':
                            $stmt->bindValue(':drawdate', $drawdate, PDO::PARAM_STR);
                            break;         
        }              
    }             
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top