MySQL在插入数据时自动更新字段

Posted

技术标签:

【中文标题】MySQL在插入数据时自动更新字段【英文标题】:MySQL automatically updating field when inserting data 【发布时间】:2014-08-08 21:18:14 【问题描述】:

我正在制作一个 Web 应用程序来让客户订购任何商品。为此,我制作了一个 mysql 数据库,其中包含以下表格:

customers orders orders-items products

customers 表中包含有关此人的所有信息,例如:

客户 ID,用于主键和自动增量 (id) 名字 (first_name) 姓氏 (last_name) 电子邮件地址 (email_address) 客户信息 (customer_info)

示例:

orders 表中包含有关它的所有具体信息,例如:

主键和自动增量 (id) 的订单 ID 它订购了哪个客户,与 customers 表 (customer_id) 中的 id 字段相关联 订单信息 (order_info) 订单需要去的位置(位置) 客户必须支付的总价 (total_price) 订单创建(创建)时间

示例:

orders-items 表中是每个客户订购的所有商品,这是由上表中的order-id 链接的。

ID,用于主键和自动增量,不用于任何关系 (id) 订单 ID,用于哪个产品对应哪个订单。这与 orders 表 (order_id) 中的 id 字段相关联 产品 ID,用于他们订购的产品,它与 products 表中的 id 字段相关联。 (product_id) 他们订购的产品数量(数量)

示例:

products 表中包含有关产品的所有信息:

主键和自动递增的 ID,与 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_pricescustomers 必须支付的费用?

【问题讨论】:

我不会在最后结账/付款之前存储应付总额,因为它经常随着添加/删除项目而变化。您可以保留总数,但每次添加/删除商品时都需要进行第二次查询,或者您可以设置 mysql trigger 以在每次商品更改时更新购物车总数。 您可能已经考虑过这个问题,但是当商品的价格发生变化时,您将如何处理呢?您是否会向 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`(idorder_idproducts_idquantity)值(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?

mysql timestamp自动更新时间问题

Navicat for mysql 中 当表一数据更新后,自动更新表2数据

JDBC插入数据超长时无法自动截断问题

mysql更新字段记录没有则添加

mysql的更新问题