多个查询相互依赖

时间:2013-01-05 20:00:44

标签: php mysql sql mysqli

我有两个相互依赖的查询,即如果不执行第一个查询则不应该执行第二个查询,而如果第二个不能执行第二个查询则不应该执行第一个查询。

INSERT INTO `table` VALUES (1,2,3)
UPDATE `otherTable` SET `val1`=1 WHERE `id`=$idOfInsert

ON DUPLICATE KEY UPDATE不是answear。

我尝试使用mysqli::multi_query,但事实证明它执行第一个,即使第二个无法执行(它会在出错时停止)。

如果我说的不清楚,请向我询问更多信息。

有人可以帮我吗?

4 个答案:

答案 0 :(得分:4)

如果您使用的引擎支持它(InnoDB,BDB),您可以使用事务。

有关示例,请参阅http://dev.mysql.com/doc/refman/5.0/en/commit.html

编辑:使用 mysqli 的快速示例:

$connection->autocommit(FALSE); // disable auto-commit and start a new transaction
$result  = $connection->query("INSERT INTO `table` VALUES (1,2,3)");
$result &= $connection->query("UPDATE `otherTable` SET `val1`=1 WHERE `id`=$idOfInsert");
if (!$result) {
  // One of the queries has failed: cancel the transaction
  $connection->rollback();
} else {
  // Both queries worked:commit the current transaction
  $connection->commit();
}
$connection->autocommit(TRUE); // enable auto-commit

您可能希望优化查询(即如果第一个失败则不执行第二个查询,使用预准备语句,......)

答案 1 :(得分:1)

我正在寻找的是交易。那时@tmuguet的答案确实对我有帮助,但是现在从时间的角度来看,我想提供一个更新的答案。

每个查询需要单独执行,并使用准备好的语句来防止SQL注入。

try {
    // Start transaction
    $mysqli->begin_transaction();

    $mysqli->query('INSERT INTO `table` VALUES (1,2,3)');

    $stmt = $mysqli->prepare('UPDATE otherTable SET val1=1 WHERE id=?');
    $stmt->bind_param('s', $idOfInsert);
    $stmt->execute();

    // Commit changes
    $mysqli->commit();
} catch (\Throwable $e) {
    // Something went wrong. Rollback
    $mysqli->rollback();
    throw $e;
}

当然要使其正常工作,您需要启用mysqli错误报告。只需在代码中new mysqli()之前添加此行即可。

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

答案 2 :(得分:-1)

使用[INSERT IGNORE]使SQL服务器忽略错误。

INSERT IGNORE INTO `table` VALUES (1,2,3);

然后使用LAST_INSERT_ID()获取插入的ID,如果没有插入则使用0。如果没有ID = 0的记录,这将使UPDATE失败。

UPDATE `otherTable` SET `val1`=1 WHERE `id`=LAST_INSERT_ID();

答案 3 :(得分:-2)

将其分成多个查询调用:

$result = mysql_query("INSERT ...");
if ($result) {
    mysql_query("UPDATE ...");
}

但是“如果不能做第二次就不要做”是不可能的。 PHP无法及时返回并警告第一个查询第二个查询失败。