【问题标题】:What is best way to insert Master/Detail records using PHP-MySQL使用 PHP-MySQL 插入主/详细记录的最佳方法是什么
【发布时间】:2018-09-10 10:15:01
【问题描述】:

我有一个销售订单主 (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.';
}

【问题讨论】:

    标签: php mysql database mysqli


    【解决方案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);,在结尾使用$mysqli->autocommit(true);

    【讨论】:

    • 超一流!像魅力一样工作!非常感谢@Bhavin
    【解决方案2】:

    将“批量插入”与“提交”和“回滚”一起使用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-26
      • 2015-12-31
      • 2014-12-14
      • 2012-10-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多