0

假设我有一个准备好的查询:

$update_rq = $DB->prepare("
  UPDATE `table`
  SET
    `A` = :a,
    `B` = :b,
    `C` = :c
  WHERE `id` = :id
  LIMIT 1
");

如果我将使用以下代码执行此查询:

$update_rq->execute(['id' => $id,'a' => 1,'b' => 2]);

我认为这个查询将设置C列的NULL值(如果这个列可以有 NULL 值,否则它会抛出一个错误,如果它不能)。

如果相应的变量未设置(等于 NULL),我是否可以修改prepareorexecute语句以更改此行为以保持C列不变( )?SET C = C

另一种方法:也许我可以在更新之前获取行,更改所需的列,然后用新值更新?

4

1 回答 1

3

您正在做的事情不起作用,您需要绑定与占位符相同数量的参数。PHP 不会隐式替换 a null,它只会失败。你可以做一些简单的事情,比如:

$data         = array('a' => 1, 'b' => 2, 'c' => null);
$data         = array_filter($data);
$placeholders = array_map(function ($col) { return "`$col` = :$col"; }, array_keys($data));
$query        = sprintf('UPDATE `table` SET %s WHERE id = :id', join(', ', $placeholders));
$stmt         = $DB->prepare($query);

$stmt->execute($data + array('id' => $id));

这将使用与现有数量一样多的占位符和值执行语句;任何null值都被完全忽略。请注意将您的列名列入白名单;这意味着您不应该接受任意列名作为用户输入,因为该"`$col` = :$col"步骤会使您面临 SQL 注入。至少做一些类似的事情:

$allowedCols = array('a', 'b', 'c');
if (array_diff_key($_POST, array_flip($allowedCols))) {
    throw new UnexpectedValueException('Received invalid data');
}
于 2014-11-11T20:31:58.070 回答