【问题标题】:oracle SQL triggeroracle SQL触发器
【发布时间】:2015-01-14 11:56:01
【问题描述】:

我应该编写一个触发器来更新我的一个表中的属性。更详细: 我有一个带有属性“orderID、customerID、date、value”的“订单”表和一个带有属性“orderID、articleID、数量”的“订单项”表。 订单中的“价值”是订单的综合价值,即每个订单商品的(价格*数量)之和。 触发器现在应该在我更新、插入或删除“订单项”中的任何内容时保持属性“值”的更新。 “INSERT”和“DELETE”的触发器主体如下所示:

IF INSERTING THEN
  UPDATE Orders
  SET value = value + (SELECT (:NEW.quantity* articles.price)
                           FROM articles
                           WHERE articles.articleID = :NEW.articleID)
  WHERE Orders.OrderID= :NEW.OrderID;
END IF;

IF DELETING THEN
  UPDATE Orders
  SET value = value - (SELECT (:OLD.quantity * articles.price)
                           FROM articles
                           WHERE articles.articleID = :OLD.articleID)
  WHERE Orders.OrderID= :OLD.OrderID;
END IF;

现在我们剩下了 UPDATING 案例。这是我的问题:当插入一个新的订单项目时,价值当然会增加,所以我可以像上面一样将新价值添加到旧的价值。 DELETING 也一样:我可以减去已删除行的值。但是对于更新,它变得棘手:根据 UPDATE 语句是增加还是减少数量,更改文章 ID 意味着价格增加或减少,或者两者都进行,价值会增加或减少。到目前为止,我的方法是使用许多不同的“IF”子句来处理这个问题(IF :OLD.quantity

【问题讨论】:

    标签: sql oracle triggers


    【解决方案1】:

    我认为您可以将所有三个的逻辑替换为:

      UPDATE Orders
          SET value = value + (SELECT (coalesce(:NEW.quantity, 0) - coalesce(:OLD.quantity, 0)) * a.price
                               FROM articles a
                               WHERE a.articleID = :NEW.articleID
                              )
          WHERE Orders.OrderID= :NEW.OrderID;
    

    请注意,您假设价格尚未更新。如果有可能,最好重新计算整个订单价格。

    【讨论】:

    • 如果我这样做,它会在“UPDATE ORDERS”行和下面的行中显示“SQL 语句被忽略”,它会显示“KEYWORD FROM not found where expected”
    【解决方案2】:

    正确的想法是计算(新旧)差异。像这样的:

    if inserting or deleting or updating then 
    
      if :NEW.quantity = :OLD.quantity and :NEW.article_id = :OLD.article_id then
    
        null;
    
      else
    
        update orders set
          value = value + 
            coalesce((
              SELECT (:NEW.quantity * articles.price) 
              FROM articles         
              WHERE articles.articleID = :NEW.articleID), 0) -
            coalesce((
              SELECT (:OLD.quantity * articles.price) 
              FROM articles         
              WHERE articles.articleID = :OLD.articleID), 0)
        where order_id = coalesce(:NEW.order_id, :OLD.order_id);
    
      end if;
    end if;
    

    【讨论】:

    • 这看起来不错,谢谢。但是,如果我想更改商品而不是更改数量怎么办?
    • 没关系。它有效,我没有正确阅读。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2015-03-26
    • 2018-04-04
    • 1970-01-01
    • 1970-01-01
    • 2020-07-21
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多