2010-10-23 86 views
1

我有一個產品,sales_order和sales_order_product表。這個mysql觸發器有什麼問題嗎?

產品的性質決定了價格和重量的頻繁變化。

客戶在提交和付款前通常會將訂單保存幾天。

由於這種滯後和價格/重量的波動,我們允許他們凍結原始訂單時的價格/重量。

我們在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 

回答

0

您的設計看起來不錯;只是幾點想法:

  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. 訂單狀態。訂單完成後會發生什麼?銷售完成後,無論發生什麼事情(更改稅率等),都應該修正這些值,因此您可能需要觸發器在更新任何內容前檢查訂單狀態。

你或許可以通過做一些基於故事板/場景的測試來排序所有這些。