【问题标题】:Insert/update script not updating at all插入/更新脚本根本不更新
【发布时间】:2018-03-23 02:07:28
【问题描述】:

我有一个脚本可以按应有的方式运行和插入,但它没有更新,至少在初始批次中没有。如果我运行脚本,第一个也是主要的 SELECT 查询将获得大约 800 条记录。它插入并执行我在下面的逻辑(脚本底部的多个 if、elseif 和 for 循环),但我需要它来处理初始选择中的每条记录。

所以:选择所有记录,对于第一条记录,在目标表上执行选择以查看该经销商的 sku 是否存在。如果没有,则插入,如果有则更新。

问题是,当我为初始数据移植运行此程序时,目标表为空,因此它不会检查任何内容。我在我的代码中添加了一个 foreach 来表示“对于每条记录,对目标表执行选择/检查,然后执行逻辑以确定是插入还是更新”

我在下面也包含了一个小提琴,但使用这些值进行选择:

(12345, 133, 1234, '2018-02-02', 10, 10),
(12345, 133, 1235, '2018-02-02', 10, 10),
(12345, 133, 1236, '2018-02-02', 10, 10),
(12346, 133, 1234, '2018-03-02', 30, 10);

逻辑是,对于每个经销商,他们最多应该记录每个sku等于他们的商店编号。

根据上面的数据,第一个sku要插入10条记录,第二个sku要插入10条记录,第三个sku要插入10条记录,然后由于第4个sku和第1个sku一样,而且日期在expire_date之前,我们将根据数量超过店面来更新该行 30 次。

逻辑很奇怪,我知道。但这部分有效,我只需要有关 foreach 逻辑的帮助,以确保我正在对初始选择中的每条记录执行检查,以便它可以实际确定是否需要更新。

我可以根据需要澄清。

$detailStatCheck = "
    SELECT 
         orderNum,
         custNum,
         sku,
         shipDate,
         quantity,
         stores
    FROM orders
    WHERE custNum= 133";

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

$existingCheck = "
    SELECT 
        sku,
        custNum,
        expire_date,
        quantity
    FROM individualProducts
    WHERE customer = :customer
        AND sku = :sku
";

$updatePlacement = "
    UPDATE individualProducts
    SET expire_date = DATE_ADD(DATE_FORMAT(CONVERT(current_date(), CHAR(20)), '%Y-%m-%d'),INTERVAL 127 DAY),
       quantity = :quantity
";

$insertPlacement = "
    INSERT ignore INTO individualProducts (sku, customer, start_date, expire_date, locations, quantity)
    VALUES(
        :sku,
        :customer, 
        date_add(convert(:SHIPDATE,date), interval 7 day) as start_date,
        date_add(convert(:SHIPDATE,date), interval 127 day) as expire_date, 
        :stores,
        :quantity)
";

$checkExisting = $MysqlConn->prepare($existingCheck);
$insert = $MysqlConn->prepare($insertPlacement);
$update = $MysqlConn->prepare($updatePlacement);

$orders = [];
while ($row2 = $detailCheck->fetch(PDO::FETCH_ASSOC)) {
    $orders[] = $row2;
     foreach($orders as $order){

     $values = [
        ":customer" => $row2["customer"],
        ":shipDate" => $row2["shipDate"],
        ":stores" => $row2["stores"],
        ":quantity" => $row2["quantity"],
        ":sku" => $row2["sku"],
     ];

     $existingRslt = $checkExisting->execute($values);
     $count3 = $checkExisting->fetch(PDO::FETCH_ASSOC);

     //if no existing records, insert. If quantity is greater than stores, insert records to equal store number. If quantity is less than stores, insert records to equal quantity

     if(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 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) && curdate() < $count3['expire_date']){
                print_r("Updating");
                if($row2["QUANTITY"] > $row2["STORES"]){
                    for($i=0; $i<$row2['STORES']; $i++){
                        try{
                            $updateRslt = $update->execute($values3);
                        }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($values3);
                        }catch(PDOException $ex){
                            echo "QUERY FIVE FAILED!!!: " . $ex->getMessage();
                        }
                    }
                }
            }else{
            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();
                    }
             }
         }
      }

$MysqlConn = null;     

这是小提琴:http://sqlfiddle.com/#!9/0efffb

编辑:

创建表语法

create table orders(
 orderNum int(11),
 custNum int(11),
 sku int(11),
 shipDate DATE,
 quantity int(11),
 stores int(11) 
);

insert into orders
values (12345, 133, 1234, '2018-02-02', 10, 10),
   (12345, 134, 1234, '2018-02-02', 10, 10),
   (12345, 135, 1234, '2018-02-02', 10, 10),
   (12346, 133, 1234, '2018-03-02', 30, 10);

create table individualProducts(
 sku int(11),
 customer int(11),
 start_date DATE,
 expire_date DATE,
 locations int(11),
 quantity int(11)
 );

【问题讨论】:

  • 我确实提供了创建表的小提琴,但我也在上述问题中添加了它们
  • 射击,抱歉,这是错误的代码。我现在更新了,应该只是更新个人产品。我只用了 2 张桌子
  • 这里最奇怪的是,您的 update 语句没有 WHERE 语句,如果该更新被调用,则该语句会导致该表中的所有注册表都被更新代码。
  • @JorgeCampos 我认为这是问题的一部分。实际上,我通过移动我的 foreach 来触发更新,但是,就像您说的那样,它正在更新每条记录。所以我需要用一个'where'子句来更新它,这是我认为循环正在为做的逻辑
  • @JorgeCampos 有没有更具体的方式来根据我的数组说update these things for this exact record?

标签: php mysql


【解决方案1】:

您可能知道,但是,如果您对错误处理更感兴趣,您可以阅读this(通用)和this(针对 PDO)文章。

更新阶段仍然很难理解。我只是希望,您至少可以从我的代码中获得一些想法。不要接受我的回答。我发布它只是为了帮助你一点。有什么想问的都可以问我。

index.php

<?php

require 'connections.php';

/*
 * ====================
 * Get the orders list.
 * ====================
 */
$sql = 'SELECT 
            orderNum,
            custNum,
            sku,
            shipDate,
            quantity,
            stores
        FROM orders
        WHERE custNum = :custNum';

$ordersStatement = $DB2conn->prepare($sql);
$ordersStatement->execute([
    ':custNum' => 133,
]);
$orders = $ordersStatement->fetchAll(PDO::FETCH_ASSOC);

/*
 * ======================================================
 * Prepare the sql for selecting the individual products.
 * ======================================================
 */
$sql = 'SELECT 
            id,
            expire_date,
            quantity
        FROM individualProducts 
        WHERE 
            sku = :sku 
            AND customer = :customer
        ORDER BY id DESC';

$productsStatement = $MysqlConn->prepare($sql);

/*
 * ====================================================
 * Prepare the sql for inserting an individual product.
 * ====================================================
 */
$sql = 'INSERT INTO individualProducts (
            sku,
            customer,
            start_date,
            expire_date,
            locations,
            quantity
        ) VALUES (
            :sku,
            :customer, 
            DATE_ADD(CONVERT(:shipDate, date), INTERVAL 7 DAY),
            DATE_ADD(CONVERT(:shipDate, date), INTERVAL 127 DAY),
            :locations,
            :quantity
        )';

$insertProductStatement = $MysqlConn->prepare($sql);

/*
 * ===================================================
 * Prepare the sql for updating an individual product.
 * ===================================================
 */
$sql = 'UPDATE individualProducts
        SET 
            expire_date = DATE_ADD(DATE_FORMAT(CONVERT(current_date(), CHAR(20)), "%Y-%m-%d"),INTERVAL 129 DAY),
            quantity = :quantity
        WHERE id = :id';

$updateProductStatement = $MysqlConn->prepare($sql);

/*
 * ==================================
 * Update/insert individual products.
 * ==================================
 */
foreach ($orders as $orderItem) {
    $orderItemCustomer = $orderItem['custNum'];
    $orderItemSku = $orderItem['sku'];
    $orderItemShipDate = $orderItem['shipDate'];
    $orderItemQuantity = $orderItem['quantity'];
    $orderItemStores = $orderItem['stores'];

    /*
     * =================================
     * Get products by sku and customer.
     * =================================
     */
    $productsStatement->execute([
        ':sku' => $orderItemSku,
        ':customer' => $orderItemCustomer,
    ]);
    $products = $productsStatement->fetchAll(PDO::FETCH_ASSOC);

    if (!$products) { // No individual products found.
        // How many products should be inserted?
        $numberOfProductsToInsert = ($orderItemQuantity >= $orderItemStores) ? $orderItemStores : $orderItemQuantity;

        // Insert the product $numberOfProductsToInsert times.
        for ($i = 0; $i < $numberOfProductsToInsert; $i++) {
            $insertProductStatement->execute([
                ':sku' => $orderItemSku,
                ':customer' => $orderItemCustomer,
                ':shipDate' => $orderItemShipDate,
                ':locations' => $orderItemStores,
                ':quantity' => $orderItemQuantity,
            ]);
        }
    } else { // Individual products found.
        $numberOfProducts = count($products);
        $numberOfUpdatedProducts = 0;
        $currentDate = date('Y-m-d', time());

        // How many products should be updated?
        $numberOfProductsToUpdate = ($orderItemQuantity >= $orderItemStores) ? $orderItemStores : $orderItemQuantity;
        $numberOfProductsToUpdate = ($numberOfProductsToUpdate >= $numberOfProducts) ? $numberOfProducts : $numberOfProductsToUpdate;

        // Update each product (maximal $numberOfProducts).
        foreach ($products as $product) {
            if ($numberOfUpdatedProducts == $numberOfProductsToUpdate) {
                break;
            }

            $productId = $product['id'];
            $productExpireDate = $product['expire_date'];

            if ($currentDate < $productExpireDate) {
                $updateProductStatement->execute([
                    ':quantity' => $orderItemQuantity,
                    ':id' => $productId,
                ]);

                $numberOfUpdatedProducts++;
            }
        }
    }
}

connections.php

<?php

// Db configs.
define('HOST', 'localhost');
define('PORT', 3306);
define('DATABASE', 'tests');
define('USERNAME', 'root');
define('PASSWORD', 'root');
define('CHARSET', 'utf8');

error_reporting(E_ALL);
ini_set('display_errors', 1); /* SET IT TO 0 ON A LIVE SERVER! */

/*
 * Create a DB2 connection.
 */
$DB2conn = new PDO(
        sprintf('mysql:host=%s;port=%s;dbname=%s;charset=%s', HOST, PORT, DATABASE, CHARSET)
        , USERNAME
        , PASSWORD
        , [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => TRUE,
    PDO::ATTR_PERSISTENT => FALSE,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
);

/*
 * Create a MySQL connection.
 */
$MysqlConn = new PDO(
        sprintf('mysql:host=%s;port=%s;dbname=%s;charset=%s', HOST, PORT, DATABASE, CHARSET)
        , USERNAME
        , PASSWORD
        , [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_EMULATE_PREPARES => TRUE,
    PDO::ATTR_PERSISTENT => FALSE,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        ]
);

创建表语法

CREATE TABLE `orders` (
  `orderNum` int(11) DEFAULT NULL,
  `custNum` int(11) DEFAULT NULL,
  `sku` int(11) DEFAULT NULL,
  `shipDate` date DEFAULT NULL,
  `quantity` int(11) DEFAULT NULL,
  `stores` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `individualProducts` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `sku` int(11) DEFAULT NULL,
  `customer` int(11) DEFAULT NULL,
  `start_date` date DEFAULT NULL,
  `expire_date` date DEFAULT NULL,
  `locations` int(11) DEFAULT NULL,
  `quantity` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

【讨论】:

    猜你喜欢
    • 2012-05-30
    • 2023-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 2020-10-24
    • 1970-01-01
    相关资源
    最近更新 更多