У меня есть сценарий, который «работает», но я упустил логику, и я пытаюсь исправить это.
По сути, приведенный ниже сценарий выбирает заказы из базы данных 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.
Имеет ли это смысл?
Я думаю, что это имеет смысл, и я знаю, что логика здесь немного странная. Вот вопрос: могу ли я взять: INVOICE и поместить его в массив, а затем, возможно, выполнить цикл foreach вокруг всего этого? То, что у меня сейчас работает, касается вставки, но обновления пропускаются, если в выбранном элементе есть строки, которые необходимо обновить.
Основная проблема в дате, верно? Например, если J1 у вас есть продукт, срок действия которого истекает J2, и вы делаете запрос J3, продукт будет «просрочен», даже если при получении заказа его не было? Или что-то в этом роде?
Но для меня, чтобы убедиться, что все ваши вставки / обновления данных в хорошем состоянии: 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
Хорошо, спасибо, вчера вечером я попробовал использовать foreach, и мне показалось, что для каждого заказа выполняется слишком много циклов, поэтому моя логика, вероятно, была отключена. Я собираюсь попробовать это еще раз и посмотреть, какие результаты я могу получить, спасибо!
Может быть, есть лучшее решение вашей проблемы, но вы знаете, чего хотите достичь лучше, чем я! Но, тем не менее, если вы будете рассматривать ваши заказы один за другим в хорошем состоянии, удачи!






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