วิธีที่ดีที่สุดในการแทรกบันทึก Master/Detail โดยใช้ PHP-MySQL คืออะไร

ฉันมีตาราง Sales Order Master (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.';
}

person Aditya Amit    schedule 10.09.2018    source แหล่งที่มา


คำตอบ (2)


คุณสามารถใช้วิธีด้านล่างเพื่อใช้การย้อนกลับและคอมมิตฟังก์ชันการทำงาน

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); ที่ตอนท้ายแทน

person Bhavin Solanki    schedule 10.09.2018
comment
สุดคลาส! ทำงานเหมือนมีเสน่ห์! ขอบคุณ @Bhavin มากครับ - person Aditya Amit; 10.09.2018

ใช้ "การแทรกแบทช์" ร่วมกับ "กระทำ" และ "ย้อนกลับ"

person AGK    schedule 10.09.2018