0

我有以下代码可以正常工作并执行我想要的操作,但我觉得我使用的代码比必要的要多。我要做的就是获取数据库单元格中的值并检查它是否为“1”,如果是,则运行另一个查询。

$isComplete = $database -> prepare("SELECT completed FROM projects WHERE id = $project_id");
$isComplete -> execute();
$result = $isComplete -> fetchAll();
$result = count($result);
if($result == 1) { $database -> exec("UPDATE projects SET num_complete = num_complete - 1 WHERE id = $parent_id"); }
4

3 回答 3

0

WHERE您可以在子句中放置一个子查询,而不是在子句中放置一个子查询,JOIN以绕过 MySQL 对在子查询和子查询中都针对表的限制UPDATE。此外,您可以在 SQL 查询中执行计算,而不是选择具有给定项目 ID 的所有行并在 PHP 中对它们进行计数。就像是:

UPDATE projects p0
    JOIN (SELECT id, count(*) AS nSiblings
            FROM projects
            WHERE id=:project GROUP BY id)
         AS p1
      ON p0.id=p1.id
  SET p0.num_complete=p0.num_complete+1
  WHERE p1.nSiblings=1

请注意,由于它是内连接,因此在子查询中指定 ID 就足够了。您也可以删除GROUP BY id,但如果您将该语句改编为其他用途,它可能会引入错误。

表设计可能存在影响此查询(和其他方面)的其他问题,但由于未提供模式,因此无法提供反馈。

于 2013-08-23T21:55:28.877 回答
0

首先,从代码量的角度来看,您的代码确实不是最佳的。
这也与您自己的描述相矛盾

而且 - 更糟糕的是 - 它很容易发生 SQL 注入。

此外,您的变量命名不一致且令人困惑。
这是检查所选值是否 = 1 的正确代码。

$stmt = $database->prepare("SELECT completed FROM projects WHERE id = ?");
$stmt->execute(array($project_id));
$isComplete = $stmt->fetchColumn();
if ($isComplete) ...

但是,我怀疑您根本不需要这样的代码。要获得已完成子任务的数量,只需一个简单的查询即可。你真的确定你需要这个num_complete领域吗?

于 2013-08-23T07:01:07.853 回答
-1

您可以使用子查询来检查更新语句中的条件。像这样的东西:

UPDATE projects SET num_complete = num_complete - 1 WHERE id = $parent_id
and (select completed from projects where id = $project_id) = 1

例如:

$st = $database->prepare("UPDATE projects SET num_complete = num_complete - 1 WHERE id = :parent_id
    and (select completed from projects where id = :project_id) = 1");
$st->bindParam(':parent_id', $parent_id, PDO::PARAM_INT);
$st->bindParam(':project_id', $project_id, PDO::PARAM_INT);
$st->execute();
于 2013-08-23T03:30:50.450 回答