问题
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;
回答1:
you should look into database transactions, they will role back all actions if one of them fails
回答2:
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
回答3:
of course the transaction is the best solution but if do not like to use it, you can use PDO to do multiple queries ,,, see this page
来源:https://stackoverflow.com/questions/27822385/enforce-inserting-records-into-multiple-tables