Php 强制将记录插入多个表

Php 强制将记录插入多个表,php,mysql,pdo,Php,Mysql,Pdo,我有两个表parent和child。仅当两个表的查询都成功时,我才希望在这两个表中插入一条记录。理想情况下,完整性将由数据库强制执行,但是,如果必要,使用应用程序这样做是可以接受的。我可能会做如下的事情,但是,似乎会有一个更优雅的方法来做到这一点。如何做到这一点 <?php //parent must be inserted first as child has a FK constraint to it $stmt1=$conn->prepare('INSERT INTO pare

我有两个表
parent
child
。仅当两个表的查询都成功时,我才希望在这两个表中插入一条记录。理想情况下,完整性将由数据库强制执行,但是,如果必要,使用应用程序这样做是可以接受的。我可能会做如下的事情,但是,似乎会有一个更优雅的方法来做到这一点。如何做到这一点

<?php
//parent must be inserted first as child has a FK constraint to it
$stmt1=$conn->prepare('INSERT INTO parent(id,data) VALUES(?,?)');
if($stmt1->execute(array(123,"foo"))) {
    $stmt2=$conn->prepare('INSERT INTO child(parent_id,data) VALUES(?,?)');
    if(!$stmt2->execute(array(123,"bar"))) {
        $stmt3=$conn->prepare('DELETE FROM parent WHERE id=?');
        $stmt3->execute(array(123));
    }
}
?>

您应该查看数据库事务,如果其中一个失败,它们将角色备份所有操作

您应该查看数据库事务,如果其中一个失败,它们将角色备份所有操作

使用事务:

您还可以设置约束,以在删除和更新时级联更改,而不是不执行任何操作。 使用事务:

您还可以设置约束,以在删除和更新时级联更改,而不是不执行任何操作。

当然事务是最好的解决方案,但是如果您不喜欢使用它,您可以使用PDO来执行多个查询,,,,

当然事务是最好的解决方案,但是如果您不喜欢使用它,您可以使用PDO来执行多个查询,,,

仍然不方便,但插入后使用触发器也可以使用过程。也可以使用事务。如果在以后的查询中出现故障,您将希望撤消以前的查询,您将在数据库中得到垃圾。我正在考虑使用触发器,但不确定,但是,不确定如果有两个以上的相关插入,将如何实现。以前从未处理过事务,将进行调查。如果使用事务,请不要忘记
mysqli\u multi\u query
,我不知道它是否接受占位符值,但在插入后使用触发器。您也可以使用过程。也可以使用事务。如果在以后的查询中出现故障,您将希望撤消以前的查询,您将在数据库中得到垃圾。我正在考虑使用触发器,但不确定,但是,不确定如果有两个以上的相关插入,将如何实现。以前从未处理过事务,将进行调查。如果使用事务,请不要忘记
mysqli\u multi\u query
,我不知道它是否接受以前使用过的事务的占位符值,但第一次查看表明它正是我想要的。但是,我不认为级联有什么意义,因为如果有任何失败,事务将回滚,否?@user1032531 Yes事务是全部或无,但如果删除父项,则不希望子表中出现孤立记录。在数据库中添加、更新和删除记录的方法不止一种。让数据库引擎来完成它的工作。你不能不采取任何行动就删除父项,不是吗?你或者其他人使用phpMySql进入表并删除父项记录。(不管理由是否充分)孤儿记录真的会把你搞得一团糟。这就是为什么引用完整性如此重要。您的接口只是一个接口。没有任何东西可以阻止某人使用或设置不同的界面。您在问题中还提到,您更希望使用数据库来管理完整性。以前从未使用过事务,但第一次查看表明它正是我想要的。但是,我不认为级联有什么意义,因为如果有任何失败,事务将回滚,否?@user1032531 Yes事务是全部或无,但如果删除父项,则不希望子表中出现孤立记录。在数据库中添加、更新和删除记录的方法不止一种。让数据库引擎来完成它的工作。你不能不采取任何行动就删除父项,不是吗?你或者其他人使用phpMySql进入表并删除父项记录。(不管理由是否充分)孤儿记录真的会把你搞得一团糟。这就是为什么引用完整性如此重要。您的接口只是一个接口。没有任何东西可以阻止某人使用或设置不同的界面。您在问题中还提到,希望使用数据库来管理完整性。
<?php

$queries=array(
    array('sql'=>'INSERT INTO parent(id,data) VALUES(?,?)',$data=>array(123,"foo")),
    array('sql'=>'INSERT INTO child(parent_id,data) VALUES(?,?)',$data=>array(123,"bar")),
    //More if necessary array('sql'=>'',$data=>array()),
);

doMultipleQueries($queries);

function doMultipleQueries($queries) {

    try {
        $conn->beginTransaction();
        foreach($queries as $query) {
            $stmt=$conn->prepare($query['sql']);
            $stmt->execute($query['data']);
        }
        $conn->commit();
        return true;
    } catch (Exception $e) {
        $conn->rollBack();
        return false;
    }
}
?>
CREATE TABLE IF NOT EXISTS `parent` (
  `id` INT NOT NULL,
  `data` VARCHAR(45) NULL,
  PRIMARY KEY (`id`))
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS `child` (
  `parent_id` INT NOT NULL,
  `data` VARCHAR(45) NULL,
  PRIMARY KEY (`parent_id`),
  CONSTRAINT `fk_child_parent`
    FOREIGN KEY (`parent_id`)
    REFERENCES `parent` (`id`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;