Создание скрипта вставки / обновления для работы с заказами по одному

У меня есть сценарий, который «работает», но я упустил логику, и я пытаюсь исправить это.

По сути, приведенный ниже сценарий выбирает заказы из базы данных db2 и каждый элемент в каждом заказе. Что я делаю, так это добавляю интервалы дат для продуктов в течение периода времени, когда, по нашему мнению, этот продукт находится на полках. У покупателя должно быть только количество записей для каждого отдельного продукта, равное количеству магазинов, которые у него есть, в пределах окна истечения срока.

Пример: если я покупатель 123 и у меня 5 магазинов. Сегодня сделал заказ на skus 1,2, и 3 и купил по 2 штуки. Это 2 записи на продукт. Завтра заказываю еще по 6 штук каждого товара; это должно добавить 3 записи для каждого продукта, а затем перезаписать самые старые записи для этих продуктов 3 раза и обновить дату истечения срока до одного дополнительного дня. Итак, в течение 2 дней я разместил несколько заказов на одни и те же 3 продукта, но количество штук было больше, чем количество моих магазинов, так что именно здесь и вступает в силу обновление. В конце дня для любого индивидуального артикула в пределах окна истечения срока действия я должен никогда не должно быть больше записей для каждого артикула, чем количество мест.

В любом случае, это работает с точки зрения вставки, и это работает для обновлений, ЕСЛИ запись уже существует, когда я делаю выбор. Но моя проблема заключается в следующем: если у select есть заказ вчера и сегодня, оба из которых содержат элементы, которые должны быть обновлены, он будет только выбрать их все и вставить, потому что во время выбора они не существовали.

Я считаю, что я решил эту проблему разбить и обработать сценарий в пакете по номеру заказа, так что я вставляю записи только для одного номера заказа, затем возвращаюсь, выбираю следующий заказ и делаю это снова. Таким образом, у каждого номера заказа есть возможность выбрать, чтобы я мог точно определить, нужно ли его обновить или вставить. Я чувствую, что это должно быть довольно просто, но я просто не знаю, как это лучше сделать.

По сути, я бы выбрал свои номера заказов, проверил мою целевую таблицу для элементов, затем вставил / обновил, а затем сделал бы все это снова для следующего номера заказа, вместо того, чтобы выбирать массив номеров заказов и просто работать с тем, что может привести к вставляется слишком много записей, а не обновляется.

Я могу уточнить, если необходимо, но любая помощь очень ценится.

<?php

//Select orders from DB2 side
$detailStatCheck = "
        SELECT 
             inv as INVOICE,
             stat as STATUS,
             cust AS CUSTOMER,
             frm AS BODY,
             cov AS MTRL,
             col AS ATTR ,
             shpdte AS SHIPPED,
             qty AS QUANTITY,
             p.stores as STORES
        FROM goods g
        inner join plant p on g.cust = p.cstno
        WHERE to_date(char(shpdte), 'YYYYMMDD') >= '2018-01-01'
    ";

    //prepare and execute to select orders
    try {
        $detailCheck = $DB2conn->prepare($detailStatCheck);
        $detailRslt = $detailCheck->execute();
        $count2 = $detailCheck->fetch();
        print_r($count2);
    } catch(PDOException $ex) {
        echo "QUERY FAILED!: " .$ex->getMessage();
    }


    //Create prepared INSERT statement
    $insertPlacement = "
        INSERT ignore INTO placedOrders (sku, category, CUSTOMER_id, start_date, expire_date, locations, order_num)
        SELECT 
            id, 
            category, 
            :CUSTOMER, 
            DATE_ADD(:SHIPPED),INTERVAL 7 DAY) as start_date,
            DATE_ADD(DATE_FORMAT(CONVERT(:SHIPPED, CHAR(20)), '%Y-%m-%d'),INTERVAL 127 DAY) as expire_date, 
            :STORES,
            :INVOICE  
        FROM sku s  
        WHERE  s.BODY=:BODY AND s.MTRL1=:MTRL AND s.ATTR1=:ATTR
    ";

    //check for existing records that are expired, which would trigger insert
    $expiredCheck = "
        SELECT 
            sku,
            CUSTOMER_id,
            expire_date
        FROM placedOrders p
            INNER JOIN sku s
                ON p.sku = s.id
        WHERE p.CUSTOMER_id = :CUSTOMER
            AND   s.BODY = :BODY
            AND   s.MTRL1 = :MTRL
            AND   s.ATTR1 = :ATTR
            AND   p.expire_date <= current_date()
    ";

    //check for existing records that are not expired, triggering update
    $validCheck = "
        SELECT 
            sku,
            CUSTOMER_id,
            expire_date
        FROM placedOrders p
            INNER JOIN sku s
                ON p.sku = s.id
        WHERE p.CUSTOMER_id = :CUSTOMER
            AND   s.BODY = :BODY
            AND   s.MTRL1 = :MTRL
            AND   s.ATTR1 = :ATTR
            AND   p.expire_date > current_date()
    ";

//prepare all update and insert queries
$checkExisting = $MysqlConn->prepare($expiredCheck);
$checkExistingValid = $MysqlConn->prepare($validCheck);
$insert = $MysqlConn->prepare($insertPlacement);
$update = $MysqlConn->prepare($updatePlacement);

    //while we have results from the order selection
    while ($row2 = $detailCheck->fetch(PDO::FETCH_ASSOC)) {

        $executionValues = [
            ":CUSTOMER" => $row2["CUSTOMER"],
            ":SHIPPED" => $row2["SHIPPED"],
            ":STORES" => $row2["STORES"],
            ":QUANTITY" => $row2["QUANTITY"],
            ":INVOICE" => $row2["INVOICE"],
            ":BODY" => $row2["BODY"],
            ":MTRL" => $row2["MTRL"],
            ":ATTR" => $row2["ATTR"],
        ];

        $checkValues = [
            ":CUSTOMER" => $row2["CUSTOMER"],
            ":BODY" => $row2["BODY"],
            ":MTRL" => $row2["MTRL"],
            ":ATTR" => $row2["ATTR"],
        ];

        try{
            //Array will contain records that are expired
            $existingRslt = $checkExisting->execute($checkValues);
            $count3 = $checkExisting->fetch(PDO::FETCH_ASSOC);

            //Array will contain records that are valid
            $existingVldRslt = $checkExistingValid->execute($checkValues);
            $count4 = $checkExistingValid->fetch(PDO::FETCH_ASSOC); 
        }catch(PDOException $ex){
                echo "QUERY FAILED!!!: " . $ex->getMessage();
        }

             // IF records do not exist, or records exist and today is after expiration date
            if (empty($count3) && empty($count4)){
                print_r("Inserting");
                if ($row2["QUANTITY"] > $row2["STORES"]){
                    for($i=0; $i<$row2["STORES"]; $i++){     
                        try{
                            $insertRslt = $insert->execute($values);
                        }catch(PDOException $ex){
                            echo "QUERY THREE FAILED!!!: " . $ex->getMessage();
                        }
                    }
                }elseif ($row2["QUANTITY"] < $row2["STORES"]){
                    for($i=0; $i<$row2["QUANTITY"]; $i++){   
                        try{
                            $insertRslt = $insert->execute($values);
                        }catch(PDOException $ex){
                            echo "QUERY THREE FAILED!!!: " . $ex->getMessage();
                        }
                    }
                }
            }elseif (!empty($count3)){
                print_r("Inserting");
                if ($row2["QUANTITY"] > $row2["STORES"]){
                    for($i=0; $i<$row2['STORES']; $i++){
                        try{
                            $insertRslt = $insert->execute($values);
                        }catch(PDOException $ex){
                            echo "QUERY FOUR FAILED!!!: " . $ex->getMessage();
                        }
                    }
                }elseif ($row2["QUANTITY"] < $row2["STORES"]){
                    for($i=0; $i<$row2["QUANTITY"]; $i++){   
                        try{
                            $insertRslt = $insert->execute($values);
                        }catch(PDOException $ex){
                            echo "QUERY FOUR FAILED!!!: " . $ex->getMessage();
                        }
                    }
                }
            }elseif (!empty($count4)){
                print_r("updating");
                if ($row2["QUANTITY"] > $row2["STORES"]){
                    for($i=0; $i<$row2['STORES']; $i++){
                        try{
                            $updateRslt = $update->execute($values);
                        }catch(PDOException $ex){
                            echo "QUERY FIVE FAILED!!!: " . $ex->getMessage();
                        }
                    }
                }elseif ($row2["QUANTITY"] < $row2["STORES"]){
                    for($i=0; $i<$row2['QUANTITY']; $i++){
                        try{
                            $updateRslt = $update->execute($values);
                        }catch(PDOException $ex){
                            echo "QUERY FIVE FAILED!!!: " . $ex->getMessage();
                        }
                    }
                }
            }
         }    

?>

Обновлено:

Основная идея заключается в следующем: если у меня есть 10 мест, и я размещаю заказ на 10 наименований товаров сегодня, еще один заказ на 30 наименований товаров завтра и еще один на 20 наименований товаров на следующий день, и скрипт запускается в этот последний день. ....... Он захватит все 3 приказа. Всего 60 skus, но в конце скрипта у меня должно быть только 10 записей для этого sku.

Имеет ли это смысл?

Я не уверен, что точно понимаю логику того, что вы делаете, но, возможно, вы можете попробовать 1 / Получить свой заказ -> использовать некоторую логику PHP, чтобы знать, что вам нужно вставить, обновить и т. д. -> использовать свой скрипт для вставьте / обновите полученный результат ИЛИ 2 / Создайте ОДИН большой запрос в соответствии с вашим порядком и выполните его ОДИН РАЗ -> $ sql = "Query1; Query2; ...; QueryX;" -> bindParam -> exectute -> таким образом, каждый запрос должен выполняться в правильном порядке

Mickaël Leger 22.03.2018 16:29

Я думаю, что это имеет смысл, и я знаю, что логика здесь немного странная. Вот вопрос: могу ли я взять: INVOICE и поместить его в массив, а затем, возможно, выполнить цикл foreach вокруг всего этого? То, что у меня сейчас работает, касается вставки, но обновления пропускаются, если в выбранном элементе есть строки, которые необходимо обновить.

Geoff_S 22.03.2018 16:39

Основная проблема в дате, верно? Например, если J1 у вас есть продукт, срок действия которого истекает J2, и вы делаете запрос J3, продукт будет «просрочен», даже если при получении заказа его не было? Или что-то в этом роде?

Mickaël Leger 22.03.2018 16:43

Но для меня, чтобы убедиться, что все ваши вставки / обновления данных в хорошем состоянии: 1 / Вы получаете ВСЕ свой заказ, который вам нужно использовать. 2 / Вы просматриваете каждый заказ и используете свою логику для построения запроса. 3 / Вы выполняете все сразу. В основном это должно выглядеть так: 1 / $orders = "SELECT...->bindParam->execute->fetchAll"; 2 / $sql = ""; foreach($orders as order) { // use your logic and update $sql with $sql .= "request"; } 3 / Выполнить $ sql

Mickaël Leger 22.03.2018 16:48

Хорошо, спасибо, вчера вечером я попробовал использовать foreach, и мне показалось, что для каждого заказа выполняется слишком много циклов, поэтому моя логика, вероятно, была отключена. Я собираюсь попробовать это еще раз и посмотреть, какие результаты я могу получить, спасибо!

Geoff_S 22.03.2018 16:52

Может быть, есть лучшее решение вашей проблемы, но вы знаете, чего хотите достичь лучше, чем я! Но, тем не менее, если вы будете рассматривать ваши заказы один за другим в хорошем состоянии, удачи!

Mickaël Leger 22.03.2018 16:57
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
4
6
71
0

Другие вопросы по теме