mysql插入主/详细记录的最佳方法是什么

kxkpmulp  于 2021-06-21  发布在  Mysql
关注(0)|答案(2)|浏览(706)

我有一个sales order master(so\ mstr)表和一个子表sales order details(sod\ det)。我正在从$\u post[]数组接收详细记录,并在脚本内部准备主记录。我的剧本应该是这样的。
插入主记录。
使用php插入详细记录 for loop (每个细节记录的查询。)
在步骤1和2成功后更新另一个表。
如果任何一个步骤失败,整个过程都应该回滚。
到目前为止,我已经尝试了以下代码。即使主插入查询失败,它也会继续插入详细记录。你知道如何确保所有的查询都能成功运行,或者在任何一个查询失败时完全回滚吗?

mysqli_autocommit($conn, FALSE);
mysqli_begin_transaction();

$insert_mstr = 'insert into so_mstr(...) values(...)';
mysqli_query($conn, $insert_mstr);

foreach ($order_details['order_details'] as $line_item) {
    $insert_line = 'INSERT INTO sod_det(...) values(...)';
    mysqli_query($conn, $insert_line);
}

if(mysqli_commit($conn)){
    insert_ar_reco(); // inserts into another table
    increment_soseq($conn, $param); // updates a table
}
else{
    echo 'Error occurred! transaction rolled back.';
}
dldeef67

dldeef671#

使用“批量插入”以及“提交”和“回滚”

piztneat

piztneat2#

您可以使用下面的方法来使用回滚和提交功能。

mysqli_query($con, "SET AUTOCOMMIT=0");
mysqli_query($con,"START TRANSACTION");
$insertMain = mysqli_query($con,''); // Insert query for Sales Order Master (so_mstr) table
foreach(($order_details['order_details'] as $line_item) {
   $insertChild = mysqli_query($con,''); // Insert query for Sales Order Details (sod_det) table
   if(!$insertChild){
       break;
   }
}

if($insert1 && $insert2) {
    mysqli_query($con,"COMMIT");
} else {
    mysqli_query($con,"ROLLBACK");
}
mysqli_query($con, "SET AUTOCOMMIT=1");

更新:如果以面向对象的方式使用mysqli,可以执行以下操作:

$mysqli->begin_transaction();
$insertMain = $mysqli->query(''); // Insert query for Sales Order Master (so_mstr) table
foreach(($order_details['order_details'] as $line_item) {
   $insertChild = $mysqli->query(''); // Insert query for Sales Order Details (sod_det) table
   if(!$insertChild){
       break;
   }
}

if($insert1 && $insert2) {
    $mysqli->commit();
} else {
    $mysqli->rollback();
}

提示:如果您使用旧的php版本5.5.0,则不能使用 $mysqli->begin_transaction(); 必须使用 $mysqli->autocommit(false); 开始和结束时 $mysqli->autocommit(true); 而不是在最后

相关问题