You can use an INSERT ... ON DUPLICATE statement.
And CoALESCE to keep an old value if null has been passed as "new" value.
<?php
$pdo = new PDO('mysql:host=localhost;dbname=test', '...', '...');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// example table
$pdo->exec('CREATE TEMPORARY TABLE foo (
id int auto_increment,
x int,
y int,
z int,
primary key(id),
unique key(x) )
');
$stmt = $pdo->prepare("
INSERT INTO
foo (x,y,z)
VALUES
(:x,:y,:z)
ON DUPLICATE KEY UPDATE
y=COALESCE(:y, y),
z=COALESCE(:z, z)
");
$stmt->bindParam(':x', $x);
$stmt->bindParam(':y', $y);
$stmt->bindParam(':z', $z);
$x = 1; $y = 1; $z=1;
$stmt->execute();
// duplicate key x=1
// overwriting y and z
$x = 1; $y = 2; $z=2;
$stmt->execute();
$x = 2; $y = 20; $z=17;
$stmt->execute();
// duplicate key x=2
// overwriting only z
$x = 2; $y = null; $z=21;
$stmt->execute();
unset($stmt);
foreach($pdo->query('SELECT * FROM foo', PDO::FETCH_NAMED) as $row) {
foreach($row as $k=>$v) {
echo $k, '=', $v, ' ';
}
echo "\n";
}
prints
id=1 x=1 y=2 z=2
id=2 x=2 y=20 z=21