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

使用PHP MySQL插入主/详细记录的最佳方法是什么,php,mysql,database,mysqli,Php,Mysql,Database,Mysqli,我有一个销售订单主表(so_mstr)和一个子表销售订单详细信息(sod_det)。我正在从$\u POST[]数组接收详细记录,并在脚本内部准备主记录。我的脚本应该像下面这样工作 插入主记录 使用PHPfor循环插入详细记录(每个详细记录的查询) 在步骤1和2成功后更新另一个表 如果任何步骤失败,整个过程应回滚。 到目前为止,我已经尝试了以下代码。即使主插入查询失败,它也会继续插入详细记录。您知道如何确保所有查询都成功运行,或者在任何查询失败时完全回滚吗 mysqli_autocommit($

我有一个销售订单主表(so_mstr)和一个子表销售订单详细信息(sod_det)。我正在从$\u POST[]数组接收详细记录,并在脚本内部准备主记录。我的脚本应该像下面这样工作

  • 插入主记录
  • 使用PHP
    for循环插入详细记录(每个详细记录的查询)
  • 在步骤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.';
    }
    

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

    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