使用PHP-MySQL插入主/明细记录的最佳方法是什么

时间:2018-09-10 10:15:01

标签: php mysql database mysqli

我有一个销售订单主(so_mstr)表和一个子表销售订单明细(sod_det)。我从$ _POST []数组接收详细记录,并在脚本本身内部准备主记录。我的脚本有望像以下一样工作。

  1. 插入主记录。
  2. 使用PHP for loop插入详细记录(对每个详细记录的查询。)
  3. 步骤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.';
}

2 个答案:

答案 0 :(得分:1)

您可以使用以下方式使用回滚和提交功能。

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);,而{{1 }}结尾

答案 1 :(得分:0)

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