4

I would like to update a MySQL row via the form below. The form works great as is but, if I leave a field blank, it changes the field in MySQL to blank as well. I would like to update the sql but skip over any fields that are blank.

I have read a few ways of doing this but they didn't seem logical. I.e. using if statements in the sql string itself. (Having MySQL do the work that should be done in PHP).

if($_SERVER['REQUEST_METHOD'] != 'POST')
{   
 echo '<form method="post" action="">
    ID: <input type="text" name="a" /><br>
    Program: <input type="text" name="b" /><br>
    Description: <textarea row="6" cols="50" name="c"></textarea><br>
    Cost: <input type="text" name="d"><br>
    <input type="submit" value="Add Link" />
 </form>';
}


try {
  $dbh = new PDO($dsn, $user, $pass);
  $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
  $stmt = $dbh->prepare('UPDATE links SET Program = :program , Descr = :descr, Cost = :cost WHERE Id= :id');

  $stmt->bindParam(":id", $_POST["a"]);
  $stmt->bindParam(":program", $_POST["b"]);
  $stmt->bindParam(":descr", $_POST["c"]);
  $stmt->bindParam(":cost", $_POST["d"]);
  $stmt->execute();
  if (!$stmt) {
    echo "\nPDO::errorInfo():\n";
    print_r($dbh->errorInfo());}
    $dbh = null;

  }
}catch (PDOException $e) {
  print "Error!: " . $e->getMessage() . "<br/>";
  die();
}
ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Jaxchief
  • 146
  • 3
  • 10
  • Do you mean you want the field to be set to `NULL` if no value is present for that field? – Robbert Jan 01 '14 at 07:27
  • Evening Robbert, No if a field is blank i want it to be ignored. So at the end of the day that blank field was left untouched in the db. – Jaxchief Jan 01 '14 at 07:29
  • Just to clarify a little more (should of done this to begin with). If I fill out the form above but leave the cost field blank. I want php/mysql to update the db with the given information but not update a blank field from the form. Thanks – Jaxchief Jan 01 '14 at 07:40
  • I think `if` statements are you only solution for this. – Robbert Jan 01 '14 at 07:44
  • you should validate input field using `!empty(trim($_POST['a']))` – Arun Killu Jan 01 '14 at 08:02
  • How would you distinguish from when a field was intentionally left blank? The better approach for update forms would be to set the value of the field on load so it will match the existing db value. If you want to prevent users from setting a field to blank on update, have a js function that resets the field to the original value if the new value is blank. Then on server side run a similar check on post to fill in those blanks *before* getting to db update. – Anthony Jan 01 '14 at 17:09

4 Answers4

6

Something like this should work

.
.
.
$q = array();
if(trim($_POST["b"]) !== ""){
    $q[] = "Program = :program";
}
if(trim($_POST["c"]) !== ""){
    $q[] = "Descr = :descr";
}
if(trim($_POST["d"]) !== ""){
    $q[] = "Cost = :cost";
}
if(sizeof($q) > 0){//check if we have any updates otherwise don't execute
    $query = "UPDATE links SET " . implode(", ", $q) . " WHERE Id= :id";
    $stmt = $dbh->prepare($query);
    $stmt->bindParam(":id", $_POST["a"]);
    if(trim($_POST["b"]) !== ""){
        $stmt->bindParam(":program", $_POST["b"]);
    }
    if(trim($_POST["c"]) !== ""){
        $stmt->bindParam(":descr", $_POST["c"]);
    }
    if(trim($_POST["d"]) !== ""){
        $stmt->bindParam(":cost", $_POST["d"]);
    }
    $stmt->execute();
}
.
.
.
ZyX
  • 52,536
  • 7
  • 114
  • 135
Class
  • 3,149
  • 3
  • 22
  • 31
  • This works perfectly. I was hunting along these lines last night but missed the if bindparam statements on my own. Thanks buddy. – Jaxchief Jan 01 '14 at 17:05
1

Change the statement:

$stmt = $dbh->prepare('UPDATE links SET Program = :program , Descr = :descr, Cost = :cost WHERE Id= :id');

As follows:

$stmt = $dbh->prepare('UPDATE links SET Program = IF(trim(:program)="", Program, :program) , Descr = IF(trim(:descr)="", Descr, :descr), Cost = IF(trim(:cost)="", Cost, :cost) WHERE Id= :id');
Rajesh Paul
  • 6,793
  • 6
  • 40
  • 57
  • I like the idea, however I prefer to have php prepare the query, and mysql execute it. Rather then mysql doing doing extra work. My train of thought is the less information sent to or required of mysql to get the result we want, the better. That said this scenario would work as well! Thanks Rajesh for your input. – Jaxchief Jan 01 '14 at 17:10
  • This strategy will definitely increase the LOC which also contributes to the time complexity of the whole operation. So handling it in the php side is not always beneficial. – Rajesh Paul Jan 01 '14 at 18:08
  • Very true. I suppose it depends on the server environment. I.e. Shared hosting Mysql Server and another IIS/Apache server. If the shared MySql server has a higher load than the web server. PHP would be more effective. However the opposite would be true if there was a higher demand on the web server. Then using the mysql server to preform more of the php tasks would make sense. This logic is of course on a very large scale. – Jaxchief Jan 01 '14 at 19:44
  • Wow. Greatly explained. Certainly there are 2 aspets. – Rajesh Paul Jan 02 '14 at 03:13
0

Check post field for empty : It will skip update query if any field data is empty.

If( $_POST["a"] && $_POST["b"] && $_POST["c"] && $_POST["d"]){

        try {
          $dbh = new PDO($dsn, $user, $pass);
          $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
          $stmt = $dbh->prepare('UPDATE links SET Program = :program , Descr = :descr, Cost = :cost WHERE Id= :id');

          $stmt->bindParam(":id", $_POST["a"]);
          $stmt->bindParam(":program", $_POST["b"]);
          $stmt->bindParam(":descr", $_POST["c"]);
          $stmt->bindParam(":cost", $_POST["d"]);
          $stmt->execute();
          if (!$stmt) {
            echo "\nPDO::errorInfo():\n";
            print_r($dbh->errorInfo());}
            $dbh = null;

          }
        }catch (PDOException $e) {
          print "Error!: " . $e->getMessage() . "<br/>";
          die();
        }


    }

Option2 Update all fields except empty:

try {
            $sql ="UPDATE links SET ";
            if($_POST["a"])
                $sql .=" Program = :program ,";
            if($_POST["b"])
                $sql .=" Descr = :descr ,";
            if($_POST["c"])
                $sql .=" Cost = :cost ,";

            $sql = rtrim($sql,',');
            $dbh = new PDO($dsn, $user, $pass);
            $dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
            $stmt = $dbh->prepare($sql);
            if($_POST["a"])
                $stmt->bindParam(":id", $_POST["a"]);
            if($_POST["b"])
                $stmt->bindParam(":program", $_POST["b"]);
            if($_POST["c"])
                $stmt->bindParam(":descr", $_POST["c"]);

            $stmt->execute();

            if (!$stmt) {
                echo "\nPDO::errorInfo():\n";
                print_r($dbh->errorInfo());}
            $dbh = null;

        }
        catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}
Awlad Liton
  • 9,366
  • 2
  • 27
  • 53
  • 2
    Isset only tells if it has been set not if it has any value – Class Jan 01 '14 at 07:35
  • This would not allow any of the fields to be updated if one was left blank correct? I'm looking to update the db with the given information but not update a blank field in the same query. – Jaxchief Jan 01 '14 at 07:42
  • Thanks @Class I am updating this answer – Awlad Liton Jan 01 '14 at 07:43
  • I was messing around with option2 before I hit the sack last night, but the problem I was having is getting "WHERE id =:Id" to inject into the SQL string using the scenario above without using implode. The answer that Class provided picked up on this train of thought. Thanks Awlad for your help! – Jaxchief Jan 01 '14 at 17:15
0

It is easier to use unnamed parameters for dynamic queries in PDO and passing them as an array in execute(). The statement will not be executed unless at least 1 parameter is passed along with the id. I have left in the echo of the derived statement and the dump of the array.

Example statement

UPDATE `links` SET `Program` = ? , `Cost` = ? WHERE `Id` = ? 

Example array

Array ( [0] => 2 [1] => 3 [2] => 2 )


if(isset($_GET['a'])){
$id = $_GET['a'];
$program = isset($_GET['b']) ? $_GET['b'] : NULL;
$descr = isset($_GET['c']) ? $_GET['c'] : NULL;
$cost= isset($_GET['d']) ? $_GET['d'] : NULL;
$params =array();
$sql = "UPDATE `links` SET "; //SQL Stub
if (isset($program)) {
    $sql .= " `Program` = ? ,";
    array_push($params,$program);   
}
if (isset($descr)) {
    $sql .= " `Descr` = ? ,";
    array_push($params,$descr); 
}
if (isset($cost)) {
    $sql .= " `Cost` = ? ,";
    array_push($params,$cost);  
}
$sql = substr($sql, 0, -1);//Remove trailing comma
if(count($params)> 0){//Only execute if 1 or more parameters passed.
    $sql .= " WHERE `Id` = ? ";
    array_push($params,$id);
    echo $sql;//Test
    print_r($params);//Test
    $stmt = $dbh->prepare($sql);
        $stmt->execute($params);
}
}
david strachan
  • 7,174
  • 2
  • 23
  • 33