简体   繁体   中英

Enforce inserting records into multiple tables

I have two tables parent and child . I would like to insert a record in both tables only if the query succeeds for both. Ideally, integrity would be enforced by the database, however, doing so using the application would be acceptable if necessary. Potentially, I could do something like the following, however, it seems like there would be a more elegant method to do so. How should this be accomplished?

<?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));
    }
}
?>

EDIT. Would something like the following work?

<?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;
    }
}
?>

Schema

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;

您应该调查数据库事务,如果其中之一失败,它们将回退所有操作

Use a transaction: http://dev.mysql.com/doc/refman/5.0/en/commit.html

Also you can set up your constraint to cascade changes ON DELETES and UPDATES instead of no action. http://dev.mysql.com/doc/refman/5.6/en/create-table-foreign-keys.html

当然,事务是最好的解决方案,但是如果不喜欢使用它,则可以使用PDO进行多个查询, 请参见本页

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM