一次一个订单使插入/更新脚本工作

Tom*_* N. 5 php mysql

我有一个“有效”的脚本,但我在逻辑上有疏忽,我正在努力纠正它。

基本上,下面的脚本从 db2 数据库中选择订单,以及每个订单上的每个项目。我正在做的是在我们认为产品上架的时间段内为产品添加日期间隔。在到期窗口内,客户应该只拥有与他们拥有的商店数量相等的任何单个产品的记录数量。

一个例子:如果我是客户 123,我有 5 家商店。今天我下了 skus 1,2 和 3 的订单,我买了 2 个。这是每个产品 2 条记录。明天我每个产品再订购 6 个;这应该为每个产品添加 3 条记录,然后覆盖这些产品的最旧记录 3 次,并将到期日期更新为一天。所以在 2 天内我为相同的 3 种产品下了多个订单,但件数比我的商店数量多,所以这就是更新的地方。在一天结束时,对于过期窗口内的任何单个 sku,我应该每个 sku 的记录永远不会超过位置数量。

无论如何,这在插入方面有效,如果在我进行选择时记录已经存在,则它适用于更新。但我的问题是:如果选择有昨天和今天的订单,两者都包含应该更新的项目,它只会选择它们并插入,因为在选择时,它们不存在。

我对此的解决方案是将其分解并按订单号批量处理脚本,这样我只需插入一个订单号的记录,然后返回并选择下一个订单并再次执行。这样,每个订单号都有机会被选中,以便我可以准确地确定是否需要更新或插入。我觉得这应该相当简单,但我只是不知道最好的方法。

基本上,我会选择我的订单号,检查我的目标表中的项目,然后插入/更新,然后为下一个订单号再次执行所有操作,而不是选择一组订单号并仅从可能导致插入而不是更新的记录太多。

如果需要,我可以澄清,但非常感谢任何帮助。

<?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();
                        }
                    }
                }
            }
         }    

?>
Run Code Online (Sandbox Code Playgroud)

编辑:

主要思想是这样的 - 如果我有 10 个地点,我今天下订单 10 个 sku,明天再下订单 30 个 sku,后天再下 20 个 sku,脚本在最后一天运行.......它将捕获所有 3 个订单。总共 60 个 sku,但在脚本结束时,我应该只有 10 个该 sku 的记录。

那有意义吗?