Каков наилучший способ вставки записей Master / Detail с использованием PHP-MySQL - PullRequest
0 голосов
/ 10 сентября 2018

У меня есть таблица мастера заказов на продажу (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 голосов
/ 10 сентября 2018

Используйте «пакетную вставку» вместе с «фиксацией» и «откатом»

0 голосов
/ 10 сентября 2018

Вы можете использовать приведенный ниже способ использования функций отката и фиксации.

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); в конце вместо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...