MySQL在插入数据时自动更新字段
Posted
技术标签:
【中文标题】MySQL在插入数据时自动更新字段【英文标题】:MySQL automatically updating field when inserting data 【发布时间】:2014-08-08 21:18:14 【问题描述】:我正在制作一个 Web 应用程序来让客户订购任何商品。为此,我制作了一个 mysql 数据库,其中包含以下表格:
customers
orders
orders-items
products
customers
表中包含有关此人的所有信息,例如:
示例:
orders
表中包含有关它的所有具体信息,例如:
customers
表 (customer_id) 中的 id
字段相关联
订单信息 (order_info)
订单需要去的位置(位置)
客户必须支付的总价 (total_price)
订单创建(创建)时间
示例:
orders-items
表中是每个客户订购的所有商品,这是由上表中的order-id
链接的。
orders
表 (order_id) 中的 id
字段相关联
产品 ID,用于他们订购的产品,它与 products
表中的 id 字段相关联。 (product_id)
他们订购的产品数量(数量)
示例:
products
表中包含有关产品的所有信息:
order_items
表 (id) 中的 product_id
字段相关联
产品名称(名称)
产品的描述(description)
产品的价格(价格)
示例:
问题:
我有这个查询:
SELECT `orders-items`.`order_id` , SUM(`orders-items`.`quantity`* `products`.`price`) total
FROM `orders-items`
INNER JOIN `Products` ON `orders-items`.`products_id` = `products`.`id`
它向我显示了每个order_id
必须支付的所有总价格的列表。
但是我该如何做到这一点,以便在插入产品时将每个 order_id
必须支付的 total_price
的值自动插入到右侧 total_price
字段内的 orders
表中 order_id
进入我的orders-list
表?
还是不要跟踪total_prices
和customers
必须支付的费用?
【问题讨论】:
我不会在最后结账/付款之前存储应付总额,因为它经常随着添加/删除项目而变化。您可以保留总数,但每次添加/删除商品时都需要进行第二次查询,或者您可以设置 mysqltrigger
以在每次商品更改时更新购物车总数。
您可能已经考虑过这个问题,但是当商品的价格发生变化时,您将如何处理呢?您是否会向 items 表中添加一条新记录,其中除了价格之外所有内容都相同,还是更新现有记录的价格?如果您通过更新更改价格,您的SUM
查询对于旧订单将不再准确,您需要将价格添加到您的订单项目表中以跟踪订单时商品的价格.
@Don'tPanic 我希望当我更改商品的价格时,它没有更新过去订单总价格中的任何内容。只有当我添加一个新的。或者你是什么意思?
@Sean 但是这仍然是跟踪客户必须支付的总价格的好方法吗?那我该怎么做呢?
【参考方案1】:
需要考虑的几件事。
为自己拥有一个total_price
是多余的。您可以随时通过对该订单商品的价格求和来了解此总计。出于性能原因拥有它可能会很有趣,但这对于您的场景真的有必要吗?很少有。
另一方面,在每个 order_item
上都有一个 price
会很有用。原因是这些产品的价格在未来可能会发生变化,而您不想丢失在特定销售时的销售量信息。
无论如何,您都可以使用以下触发器更新您的total_price
:
DELIMITER $$
CREATE TRIGGER order_items_insert AFTER INSERT ON `orders-items` FOR EACH ROW
BEGIN
UPDATE orders o INNER JOIN (SELECT i.order_id id, SUM(i.quantity * p.price) total_price FROM `orders-items` i INNER JOIN products p ON p.id = i.products_id AND i.order_id = new.order_id) t ON t.id = o.id SET o.total_price = t.total_price;
END$$
CREATE TRIGGER order_items_update AFTER UPDATE ON `orders-items` FOR EACH ROW
BEGIN
UPDATE orders o INNER JOIN (SELECT i.order_id id, SUM(i.quantity * p.price) total_price FROM `orders-items` i INNER JOIN products p ON p.id = i.products_id AND i.order_id = new.order_id) t ON t.id = o.id SET o.total_price = t.total_price;
END$$
CREATE TRIGGER order_items_delete AFTER DELETE ON `orders-items` FOR EACH ROW
BEGIN
UPDATE orders o INNER JOIN (SELECT i.order_id id, SUM(i.quantity * p.price) total_price FROM `orders-items` i INNER JOIN products p ON p.id = i.products_id AND i.order_id = old.order_id) t ON t.id = o.id SET o.total_price = t.total_price;
END$$
DELIMITER ;
【讨论】:
当我尝试将insert
新记录添加到orders-items
表中时,它给了我一个Invalid use of group function
错误消息。这是我要运行的查询:@ 987654329@broodjes-service.
orders-items`(id
,order_id
,products_id
,quantity
)值(NULL,'3','3','3')`
我发现它的这部分工作不正常:SET o.total_price = sum(i.quantity * p.price)
。每当我用另一个值替换整个sum
时。它被插入正确的位置。但总和不起作用。
试试GROUP BY o.id
,它可能会修复总和。
那没用,但我做了一些研究,当我使用子查询时它确实有效。现在是这样的:SET o.
total_price` = (SELECT sum(i.quantity * p.price))` 可以吗?顺便说一句,当我尝试安装 trigger
进行删除时,它给了我这个错误: UPDATE orders o INNER JOIN orders-items
i ON o.id = i.order_id INNER JOIN products
p ON p.id = i.products_id #1363 - There is no NEW row in on DELETE trigger
有什么我可以做的吗?我什至不明白它在说什么。
哦,删除时使用old.id
而不是new.id
【参考方案2】:
一个选项是trigger
,在插入新客户时执行。
您也可以选择stored procedure
。有了这个,您只需要调用过程InsertCustomer
,数据库会为您处理价格更新->您的应用程序中不会有这些依赖项。
另一种方法是在 transaction
中执行 2 个查询(插入和更新)。但为此我推荐Domain Driven Design
。您将拥有一个服务,该服务具有方法CreateCustomer(Customer $customer)
,它执行插入查询,然后执行更新查询。成功时提交事务并返回 true,如果不成功,则取消事务并返回 false。仅在服务(了解业务逻辑)的帮助下操作数据应该是您自己的约定。
【讨论】:
对我来说这将是两个的组合(调用存储过程的触发器)。以上是关于MySQL在插入数据时自动更新字段的主要内容,如果未能解决你的问题,请参考以下文章
当新数据插入 MySQL 数据库时,如何自动更新 recyclerView?