【问题标题】:PHP looping over query to perform conditional inserts or updatesPHP循环查询以执行条件插入或更新
【发布时间】:2019-06-02 12:56:51
【问题描述】:

我有一个似乎一直在运行的 php 脚本,但现在我想知道我的某些逻辑是否可能关闭。

我从一个日期范围内的数据库表中选择记录,并将其放入一个名为$validCount的数组中

如果该数组不为空,则意味着我有可用的值更新有效记录,如果它为空,我只需插入。插入的技巧是,如果STORES 小于Quantity,则它只插入与STORES 一样多的数量,否则它插入与Quantity 一样多的数量。

所以如果插入的记录有

Stores: 14 Quantity:12

那么它只会插入 12 条记录,但如果它有

Stores:1  Quantity:20

它只会插入 1 条记录。

简而言之,对于每个客户,我应该只拥有与他们拥有商店一样多的有效记录(在有效日期范围内)。如果他们有 20 家商店,我可以有 1 或 2 条记录,但绝不应该有 30 条。

似乎更新工作正常,但我不确定它是否更新了正确的记录,尽管在某些情况下它似乎只是插入了太多而不考虑过去更新的记录。

这里的逻辑是否看起来完全不正确?

if(!empty($validCount)){
        for($i=0; $i<$row2['QUANTITY']; $i++){
            try{
                $updateRslt = $update->execute($updateParams);
            }catch(PDOException $ex){
                $out[] = $failedUpdate;
            }
        }
}else{  
    if($row2["QUANTITY"] >= $row2["STORES"]){
        for($i=0; $i<$row2["STORES"]; $i++){     
            try{
                $insertRslt = $insert->execute($insertParams);
            }catch(PDOException $ex){
                $out[] = $failedInsertStore;
            }
        }
    }elseif($row2["QUANTITY"] < $row2["STORES"]){
        for($i=0; $i<$row2["QUANTITY"]; $i++){   
            try{
                $insertRslt = $insert->execute($insertParams);
            }catch(PDOException $ex){
                $out[] = $failedInsertQuantity;
            }
        }
    }
}

更新:

假设客户 123 购买了 4 件产品 A,他们有 10 个地点

customerNumber  |  product  |  category  |  startDate  |  expireDate  | stores
----------------------------------------------------------------------------------
123                 1           A           2018-08-01    2019-03-01      10
123                 1           A           2018-08-01    2019-03-01      10
123                 1           A           2018-08-01    2019-03-01      10
123                 1           A           2018-08-01    2019-03-01      10

因为他们购买的数量少于商店数量,我插入了 4 条记录。现在,如果我的$validCheck 查询选择了所有 4 条记录(因为它们在有效的日期范围内)并且我的循环看到该数组不为空,它知道它需要更新这些记录或插入。假设他们这次买了 15 个。然后我需要插入 6 条记录,然后更新其他 9 条记录的到期日期。

customerNumber  |  product  |  category  |  startDate  |  expireDate  | stores
----------------------------------------------------------------------------------
123                 1           A           2018-08-01    2019-03-11      10
123                 1           A           2018-08-01    2019-03-11      10
123                 1           A           2018-08-01    2019-03-11      10
123                 1           A           2018-08-01    2019-03-11      10
123                 1           A           2018-08-01    2019-03-11      10
123                 1           A           2018-08-01    2019-03-11      10
123                 1           A           2018-08-01    2019-03-11      10
123                 1           A           2018-08-01    2019-03-11      10
123                 1           A           2018-08-01    2019-03-11      10
123                 1           A           2018-08-01    2019-03-11      10

在有效日期范围内,该客户和产品最多只能有 10 条(商店计数)记录。一旦该客户/产品的行数达到相当于商店的行数,它现在需要通过并更新等于数量

更新

目前正在运行:

    $total = $row2['QUANTITY'] + $validCheck;
    if ($total < $row2['STORES']) {
        $insert_count = $row2['QUANTITY'];
        $update_count = 0;
    } else {
        $insert_count = $row2['STORES'] - $validCheck; // insert enough to fill all stores
        $update_count = ($total - $insert_count); // update remainder
    }

    foreach ($i = 0; $i < $insert_count; $i++) {
        try {
            $insertRslt = $insert->execute($insertParams);
        } catch(PDOException $ex){
            $out[] = $failedInsertStore;
        }
    }
    if ($update_count > 0) {
        try {
            $updateParams[':UPDATELIMIT'] = $update_count;
            $updateRslt = $update->execute($updateParams);
        }  catch(PDOException $ex){
            $out[] = $failedInsertStore;
        }
    }

【问题讨论】:

  • 您没有在循环期间修改$updateParams$insertParams。所以你只是一遍又一遍地更新或插入相同的行。
  • 对不起,我的意思是说参数是在 while 循环之外设置的,但这发生在 while 循环内
  • 这没有帮助。他们需要在for 循环中进行更改。
  • 我想我很困惑,我该怎么做?
  • 很难从你写的内容中分辨出来。我猜你应该使用$i 来索引包含有关要更新或插入的记录的信息的数组。

标签: php sql


【解决方案1】:

我觉得逻辑应该是这样的:

$total = $row2['QUANTITY'] + $validCheck;
if ($total < $row2['STORES']) {
    $insert_count = $row2['QUANTITY'];
    $update_count = 0;
} else {
    $insert_count = $row2['STORES'] - $validCheck; // insert enough to fill all stores
    $update_count = ($total - $insert_count); // update remainder
}

然后使用$insert_count 作为for 循环中的重复计数以插入新行。 UPDATE 查询应包含LIMIT :limit,然后您可以将$update_count 绑定到:limit 占位符。

for ($i = 0; $i < $insert_count; $i++) {
    try {
        $insertRslt = $insert->execute($insertParams);
    } catch(PDOException $ex){
        $out[] = $failedInsertStore;
    }
}
if ($update_count > 0) {
    try {
        $updateParams[':limit'] = $update_count;
        $updateRslt = $update->execute($updateParams);
    }  catch(PDOException $ex){
        $out[] = $failedInsertStore;
    }
}

【讨论】:

  • 我认为这是有道理的。我正在使用 PDO,但我想我可以弄清楚如何在更新查询中使用 $update_count。至于插入,您是说我会在迭代器块中使用 $insert_count 吗?所以for($i=0; $i&lt;$row2["QUANTITY"]; $i++) 我会使用 $insert_count 而不是 $i?
  • 我只是想弄清楚如何将您的答案合并到我现有的块中的整体结构
  • for ($i = 0; $i &lt; $insert_count; $i++)
  • 啊,我明白了,谢谢!我会试试这个,看看效果如何
  • 所有这些都应该在我现有的检查 $validCheck 是否为空的 if 语句之前?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-25
  • 1970-01-01
  • 2013-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多