有没有办法在实际插入或更新之前测试mysql插入或更新?

时间:2014-01-30 23:26:55

标签: php mysql insert

我的PHP / Mysql脚本分阶段运行:

Insert Customer info
  Get new customer's ID via mysqli_insert_id(blah)
Insert into ADDRESS using new customer's ID
Insert into PHONE using new customer's ID
Insert into CONTACTS using new customer's ID

我的问题是:如果后面的一个插入语句出现问题,MYSQL当然会停止并抛出错误,但初始的Customer INSERT已经触发并且成功了。现在,如果我们返回并更正输入中的错误并尝试再次执行此操作,我们将为此客户提供多个部分条目。

所以问题:有没有办法测试所有MySQL插件的错误,一旦找不到,那么继续提交它们吗?

例如:

Insert Customer info (check for would-be errors; don't actually insert)
  Get new customer's ID...
Insert into ADDRESS...(check for would-be errors; don't actually insert)
Insert into PHONE...(check for would-be errors; don't actually insert)
Insert into CONTACTS...(check for would-be errors; don't actually insert)

好的,既然没有抛出任何错误而且实际上没有插入任何内容,请执行所有预先筛选的插入!

这是否存在?

4 个答案:

答案 0 :(得分:4)

使用MySQL事务。

事务是一组连续的数据库操作操作,就像它是一个单独的工作单元一样。换句话说,除非组内的每个单独操作都成功,否则交易永远不会完成。如果事务中的任何操作失败,整个事务将失败。

实际上,您会将许多SQL查询添加到一个组中,并且您将作为事务的一部分一起执行所有这些查询。

阅读本教程关于MySQL transaction

的内容

答案 1 :(得分:2)

是的,事务允许您执行一系列查询,并在最后提交所有这些更改,或者在其中一个查询失败时将其回滚。
如果您使用的是PDO,基本设置如下:

//optional
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try
{
    $pdo->beginTransaction();
    $stmt = $pdo->prepare();
    $pdo->query();
    //in short, all your queries here
    $pdo->commit();//commit changes to DB
}
catch (PDOException $e)
{
    $pdo->rollBack();//Nothing is changed in DB
}

当然,事务在事务安全存储引擎(InnoDB,BerkeleyDB,ndbcluster)上运行得最好。从MySQL 5开始,事务在MyISAM上工作,但为了使它们成为原子,因此可以安全使用,你必须自己锁定和解锁表。
the mysql docs for more details

答案 2 :(得分:0)

交易最适合回滚状态。 ifthats不可能在带有insert的语句前面加上它,它应该让你知道任何错误

答案 3 :(得分:0)

以下是使用mysqli支持我的评论的示例:

if (isset($_POST) && isset($_POST['whatever']))
{

    $con = new mysqli("localhost", "user", "pw", "db");
    // begin transaction by setting autocommit to false;
    $con->autocommit(FALSE);

    $stmt = $con->prepare("INSERT INTO `something` (`data`) VALUES (?)");
    $stmt->bind_param("s", $_POST['whatever']);
    $stmt->execute();
    if (!$stmt)
    {
        $con->rollback();
    }
    else
    {
        $con->commit();
    }

    $stmt->close();
}

你应该知道交易需要innodb表。它有助于检查规格: http://dev.mysql.com/doc/refman/5.0/en/commit.html

有关详细信息,请参阅barranka的评论