Что-то не так с этим триггером MySQL? - PullRequest
1 голос
/ 23 октября 2010

У меня есть таблица product, sales_order и sales_order_product.

Характер продукции диктует частые изменения цены и веса.

Клиенты часто экономят заказы за несколько дней до их отправки и оплаты.

Из-за этого лага и колебаний цены / веса мы разрешаем им замерзать в цене / весе во время первоначального заказа.

Мы сохраняем сумму заказа (промежуточный итог), налог с продаж, вес заказа, а также некоторые другие вещи в таблице sales_order.

Я знаю, что не рекомендуется иметь какую-либо бизнес-логику на уровне базы данных, хотя я считаю это больше средством поддержания ссылочной целостности.

Ниже приведен один из триггеров, которые я использую для расчета вышеупомянутых данных. Я только начал проверять это и пока все хорошо. С точки зрения производительности, я не видел никаких проблем, но мое тестирование было не очень обширным.

Есть ли что-нибудь в этом триггере, которое выглядит неправильно? Я спрашиваю, потому что, хотя я использовал триггеры для таких вещей, как отметки времени, я никогда не использовал их в этом качестве (и, учитывая, что мы говорим о деньгах, я не хочу испортить что-то, что может потерять меня в моей работе).

Я понимаю, что, вероятно, не очень хорошая идея жестко кодировать ставку налога, и я, вероятно, изменю ее, когда придет время.

CREATE TRIGGER after_sales_order_product_update
AFTER UPDATE ON sales_order_product
FOR EACH ROW
BEGIN

    SET @product_amount = (SELECT SUM(quantity * unit_price) 
                           FROM sales_order_product 
                           WHERE sales_order_id = OLD.sales_order_id),
        @product_discount = (SELECT SUM(quantity * unit_discount) 
                             FROM sales_order_product 
                             WHERE sales_order_id = OLD.sales_order_id),
        @total_weight = (SELECT SUM(quantity * unit_weight) 
                         FROM sales_order_product 
                         WHERE sales_order_id = OLD.sales_order_id),
        @tax_amount = ROUND(@product_amount * 0.0975,2);

    UPDATE sales_order 
    SET product_amount = @product_amount,
        product_discount = @product_discount,
        tax_amount = @tax_amount,
        total_weight = @total_weight,
        product_total = product_amount - product_discount
    WHERE sales_order_id = OLD.sales_order_id;

END

1 Ответ

0 голосов
/ 09 декабря 2010

Ваш дизайн выглядит хорошо; всего несколько мыслей:

  1. Ваш триггер срабатывает только после UPDATE. Как насчет того, когда строка сначала INSERT ed или DELETE d позже?
  2. А как насчет NULL с? Если какое-либо из основных полей (quantity, unit_price, unit_discount, unit_weight) может быть нулевым, это даст вам нулевые значения в производных полях, которые вы не ожидаете.
  3. Нет строк (NULL снова). Может ли sales_order не иметь sales_order_products, скажем, если клиент удаляет одну строку из своей корзины? В этом случае вы, вероятно, захотите, чтобы значения sales_order были равны нулю, что может потребовать специального кодирования.
  4. Статус заказа. Что происходит после прохождения заказа? После завершения продажи эти значения должны быть зафиксированы независимо от того, что еще происходит (изменения налоговых ставок и т. Д.), Поэтому вам может потребоваться ваш триггер, чтобы проверить состояние заказа, прежде чем что-либо обновлять.

Вероятно, вы можете разобраться со всем этим, выполнив некоторые раскадровки / тестирование на основе сценариев.

...