【问题标题】:selectively UPDATING old rows when INSERTING new ones into table (trigger issue) in MySQL在 MySQL 中将新行插入表(触发问题)时选择性地更新旧行
【发布时间】:2014-05-22 15:33:02
【问题描述】:

我今天在我们的 MySQL 数据库中设计触发器语句时遇到了一个小问题:

我们有以下相关表格:

  • 报价(quote_key、date、discount_rate、discount_period、supplier_key)
  • part (part_key, part_name, ...)
  • part_quote (pq_key, part_price, fk_quote_key, fk_part_key)
  • part_approval (papproval_key, is_approved, fk_part_quote_key)

现在解释一下逻辑:

每个供应商都会针对制造过程中的不同投入(例如零件和组件)发布报价。如果某个零件的价格合适,它们将被批准用于制造,因此可以被我们的工程师使用。由于我们希望能够接收来自不同供应商的相同零件的报价以进行比较,因此我尝试使用 part_quote 和 part_approval 表来模拟这个过程。

关于我的问题:如果我想批准新的 part_quote,我希望将所有(或最近的)旧报价中的 BOOL 标志“is_approved”自动设置为 FALSE。

我尝试通过发出触发语句来完成此操作: 在插入 part_approval 之前创建触发器 update_approval 每一行 --- ??

我在选择要更新的正确行时遇到一些问题:

  1. 如何选择 part_key,它将最终识别所有需要更新的相关行?
  2. 如何只选择旧的(或最近的)行?

我很想包括一个筛选器,但不幸的是,我还没有 10reps:/

提前非常感谢您, 祝一切顺利, 马吕斯

【问题讨论】:

    标签: mysql sql triggers sql-update sql-insert


    【解决方案1】:

    首先,我将尽我所能按原样回答您的问题,因为了解更多有关如何使用触发器的信息会很有帮助。然后我会解释为什么你实际上不应该使用触发器。

    触发器提供了对两个特殊别名的访问,这在其他情况下是不可用的:OLD 和 NEW。 NEW 允许您访问新值并在更新/插入触发器中工作。 OLD 允许您访问旧值并在更新/删除触发器中工作。

    对于您的情况,您可能需要这样的东西:

    CREATE TRIGGER `update_approval` BEFORE INSERT ON `part_approval`
    FOR EACH ROW
    UPDATE `table_x` SET `value` = y WHERE `z` = NEW.a;
    

    有关更多信息和一些有用的触发器示例,我建议阅读以下内容:http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html

    但是,MySQL 中的触发器无法更新触发它们的同一个表,这正是您想要做的。有人在这里提出了一个很好的问题:MySQL - Trigger for updating same table after insert 和一个很好的答案,在这种情况下您应该使用存储过程。

    【讨论】:

      【解决方案2】:

      我不确定这是否能完全解决我的问题,但根据您的建议,我发现了一些有用的帖子,它们能够在包含多个语句的触发器中实现类似的更新。

      CREATE TRIGGER update_approval BEFORE INSERT ON part_approval
      FOR EACH ROW BEGIN 
      DECLARE part_id INT;
          SELECT part_key INTO part_id
          FROM part p, part_quote pq, part_approval a 
          WHERE NEW.part_quote_key=pq.part_quote_key AND pq.part_key = p.part_key;
      UPDATE part p, part_quote pq, part_approval a 
          SET a.is_approved=DEFAULT 
          WHERE pq.part_key=part_id AND a.approval_date<NEW.approval_date;
      END;
      

      只能在数据库填充后的星期一试用。 感谢您的帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-23
        • 1970-01-01
        • 2015-11-06
        • 2018-02-20
        • 2014-07-10
        • 1970-01-01
        • 2013-05-24
        • 1970-01-01
        相关资源
        最近更新 更多