【问题标题】:MySQL automatically updating field when inserting dataMySQL在插入数据时自动更新字段
【发布时间】: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 但是这仍然是跟踪客户必须支付的总价格的好方法吗?那我该怎么做呢?

标签: php mysql sql database


【解决方案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。仅在服务(了解业务逻辑)的帮助下操作数据应该是您自己的约定。

【讨论】:

  • 对我来说这将是两个的组合(调用存储过程的触发器)。
猜你喜欢
  • 2018-02-19
  • 1970-01-01
  • 2012-11-14
  • 2011-12-13
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2015-01-07
  • 2019-05-30
相关资源
最近更新 更多