Строка UPDATE при триггере UPDATE, условие нескольких таблиц

Я работаю с Shopware, и одна странность сводит меня с ума :( Так что сначала я объясню, в чем проблема.

Помимо обычных товаров, есть изделия с несколькими вариантами, например, рубашки разных размеров. Это тот же товар в XS, S, M, L и / или разных цветах ... но имеет разные номера заказов и, вероятно, разные цены.

Итак, в Shopware у вас есть таблица с основными данными о товарах, одна с подробными данными, а другая с возможными данными о ценах.

У статей с несколькими вариантами есть поля configurator_set_id и main_detail_id, установленные в таблице статей. Моя проблема в том, что у нас есть магазин, в котором много таких вариантов, и тот, кто строит логику магазина ... вероятно, был пьян. Если основной товар вариантного товара неактивен (отсутствует на складе, деактивирован и т. Д.), Весь вариантный товар больше не может быть куплен ... нет возврата к следующему варианту, он все еще находится в магазине, но вы не можете это сделать. что-нибудь вообще.

Так что я подумал, что все будет проще, просто обновите статью, если статус вариантов изменится ... но именно здесь мои проблемы начинаются. Итак, сначала структура таблицы:

s_articles:

+----+--------+----------------+---------------------+  
| id | active | main_detail_id | configurator_set_id |  
+----+--------+----------------+---------------------+  

s_articles_details:

+------+---------+-----------+
|  id  | active  | articleID |
+------+---------+-----------+

s_articles_prices

+----+-----------+-----------------+-------+
| id | articleID | articledetailID | price |
+----+-----------+-----------------+-------+

Для создания статьи Shopware в основном берет данные из s_articles, объединяет их с данными из s_articles_details, где id = s_articles.main_details_id.

Я пытался добиться следующего:

  1. Если s_articles_details обновлен, получите идентификатор строки, которая была обновлена.
  2. Проверьте, соответствует ли идентификатор main_detail_id в таблице s_articles
  3. Если он обновляет строку, установите main_detail_id = (s_articles_prices.articledetailID ГДЕ s_articles_prices.articleID = id AND min (s_articles_prices.price))

* Я знаю, что это не сработает, но, надеюсь, это описывает то, что я думаю

Причуды:

  • может быть более одного совпадения из s_articles_prices db
  • это должен быть активный вариант / цена, которая определяется через таблицу s_articles_details

Мы будем благодарны за любую помощь или толчок в правильном направлении (пока я стараюсь не биться головой о стену ...)

РЕДАКТИРОВАТЬ: окончательное решение

jean-françois-savard указал мне правильное направление, поэтому я придумал следующее решение:

DELIMITER $$
CREATE TRIGGER update_maindetailid_after_update AFTER UPDATE ON s_articles_details
FOR EACH ROW
BEGIN

    DECLARE ArticleDetailID INT(11);

    SELECT  p.articledetailsID
    INTO ArticleDetailID
    FROM s_articles_prices p, s_articles_details d
    WHERE p.articleID = NEW.articleID 
        AND d.id = p.articledetailsID
        AND d.active
    ORDER BY p.price, d.ordernumber ASC
    LIMIT 1;

    IF ArticleDetailID <> "" THEN
        UPDATE s_articles SET s_articles.main_detail_id = ArticleDetailID 
        WHERE s_articles.id = NEW.articleID
            AND s_articles.main_detail_id <> ArticleDetailID;
    END IF;

END$$;
DELIMITER ;

person maybeonline    schedule 09.02.2015    source источник


Ответы (1)


  • Trigger это то, что вам здесь нужно.
  • Создайте триггер, который будет срабатывать каждый раз при обновлении s_articles_details
  • Обратитесь к новому значению с помощью ключевого слова NEW в теле триггера.
  • В соответствии с новым значением выполните ваше условие и update/insert правильные значения в других таблицах.

Фрагмент, который поможет вам начать работу

DELIMITER $$
CREATE TRIGGER tr_au_s_articles_details AFTER UPDATE ON s_articles_details
FOR EACH ROW
BEGIN
   -- Here you can access the id of the updated article New.id
   -- update/insert depending on the condition of the newvalue.
   -- Check if id corresponds to a main_detail_id in the s_articles table
   -- Here an int : select count(id) from s_articles where main_detail_id = new.id
END;
DELIMITER ;

Дополнительную информацию о синтаксисе Trigger см. В документации.

Я не буду ложить / кормить код, но думаю, теперь вы легко сможете решить эту проблему :).

person Jean-François Savard    schedule 09.02.2015
comment
Большое спасибо за правильное направление :) Я думаю, что отсюда это был бы самый простой способ просто вызвать хранимую процедуру, обновлю завтра, мне действительно нужно немного поспать. - person maybeonline; 10.02.2015
comment
Пожалуйста, но почему бы не использовать спусковой крючок, предназначенный для этого? Это похоже на процедуру, которая автоматически вызывается при обновлении. - person Jean-François Savard; 10.02.2015
comment
Конечно, вы правы, я, наверное, подумал о том, чтобы поместить это в процедуру, чтобы не писать снова, если мне это понадобится в другом месте ... полная чушь :) Но еще раз: спасибо за подсказку, сэр! Это было именно то, что мне нужно. - person maybeonline; 10.02.2015
comment
@maybeonline Пожалуйста :). Обратите внимание, что сохранение части trigger в procedure - хорошая идея, если вы думаете, что будете где-то повторно использовать ее, нет проблем с вызовом процедуры из триггера. - person Jean-François Savard; 10.02.2015