这个mysql触发器有什么问题吗?
我有一个产品、 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
I have a product, sales_order, and sales_order_product table.
The nature of the products dictate frequent changes to price and weight.
The customers often times save orders for a few days before submitting and paying for them.
Because of this lag and the price/weight fluctuations, we allow them to freeze in the price/weight at the time of the original order.
We save the order amount (subtotal), sales tax, order weight, among a few other things in the sales_order table.
I know it's not recommended to have any business logic within the database layer though I see this as more of a means to maintain referential integrity.
Below is one of the triggers I use to calculate the aforementioned data. I've only started to test it out and so far so good. Performance wise, I haven't seen any issues thus far but my testing hasn't been very extensive.
Is there anything about this trigger that doesn't look right? I ask because though I've used triggers for things like time stamps I've never really used them in this capacity (and considering we are talking about money, I don't want to screw something up that could lose me my job).
I realize it's probably not a good idea to hard code the tax rate, and I'll probably change that when the time comes.
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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的设计看起来不错;只是一些想法:
UPDATE
之后触发。当一行首先被插入,或者稍后被删除时会怎么样?NULL
又如何呢?如果任何核心字段(quantity
、unit_price
、unit_discount
、unit_weight
)可能为 null,则将给出您在派生字段中设置了您可能不期望的空值。NULL
)。假设客户从购物车中删除了一行,sales_order
是否可以没有sales_order_products
?在这种情况下,您可能希望 sales_order 值为零,这可能需要特殊编码。您可能可以通过进行一些故事板/基于场景的测试来解决所有这些问题。
Your design looks good; just a few thoughts:
UPDATE
. What about when a row is firstINSERT
ed, orDELETE
d later?NULL
s? If any of the core fields (quantity
,unit_price
,unit_discount
,unit_weight
) could be null, that will give you nulls in the derived fields which you might not be expecting.NULL
s again). Could asales_order
have nosales_order_products
, say if the customer deletes the one row from their shopping cart? In that case you probably want thesales_order
values to be zero, which might need special coding.You can probably sort all these out by doing some storyboard/scenario-based testing.