【问题标题】:Oracle Transaction Update Amount From One Table to Another从一个表到另一个表的 Oracle 事务更新量
【发布时间】:2017-04-13 14:51:37
【问题描述】:

我正在创建一个包含四个不同表的数据库:

CUSTOMER (PK CUST_ID, CUST_NAME, CUST_ADDRESS)

INVOICE (PK INVOICE_ID, FK CUST_ID, INVOICE_AMOUNT)

PRODUCT (PK PRODUCT_ID, PRODUCT_NAME, PRODUCT_COST)

INVOICE_ITEM (PK FK INVOICE_ID, PK FK PRODUCT_ID, 
INVOICE_ITEM_QUANTITY, INVOICE_ITEM_PRICE)

我需要创建一个 1) 的事务。将数据插入新的CUSTOMER, 2)。将数据插入新的INVOICE(发票金额设置为0),3)。插入两个新的INVOICE_ITEM 的数据(其中一行将INVOICE_ITEM_QUANTITY 设置为2,INVOICE_ITEM_PRICE 设置为5.00,另一行设置为1 和10.00)。

我可以使用插入命令毫无问题地完成所有这些操作,但下一步是让我失望:

'更新 INVOICE_AMOUNT 以将第 3 步中添加的行项目添加到 INVOICE_ITEM_PRICE 字段。无论此 INVOICE 是否存在现有 INVOICE_ITEM 行,您都必须使用可以工作的查询来执行此操作。您的查询无法对金额进行硬编码。'

我不知道该怎么做。我一直在研究解决方案,但没有找到任何描述这个问题的方法,只有在列名相同的情况下才有效。

我可以直接将值插入INVOICE_AMOUNT,但是这样会被认为是对答案进行硬编码,对吗?所以我一直在尝试按照

UPDATE INVOICE
SET INVOICE_ITEM.INVOICE_ITEM_PRICE = INVOICE.INVOICE_AMOUNT
WHERE INVOICE.INVOICE_ID = INVOICE_ITEM.INVOICE_ID

但我无法让此代码的任何变体正常工作。我确信有一些非常简单的答案会让我觉得自己很愚蠢,但如果有人能提供帮助,我将不胜感激。

【问题讨论】:

  • 对我来说 Invoice_Amount 应该是 sum(invoice_Item.Invoice_Item_Price*Invoice_Item_Quantity) 所以你需要得到那个总和确保它不为空(或者如果它为空至少让它为 0)
  • 我也知道这一点,但在我的作业中指出:你是否应该有一个 INVOICE_AMOUNT 字段是有问题的,因为你总是可以查询 INVOICE_ITEM 表并总结 INVOICE_ITEM_QTY *每个发票项目的 INVOICE_ITEM_PRICE。然而,对于这个任务,我们假设我们想要这样做。

标签: sql database oracle


【解决方案1】:

这可能有点笨拙,但考虑到你所拥有的并且没有迹象表明当时使用了 PL/SQL;

UPDATE invoice i
SET    i.invoice_amount = (SELECT SUM(ii.invoice_item_quantity * ii.invoice_item_price)
                           FROM   invoice_item ii
                           WHERE  ii.fk_invoice_id = 1.invoice_id)
WHERE  i.invoice_id = (SELECT MAX(invoice_id)
                       FROM   invoice
                       WHERE  fk_cust_id = (SELECT MAX(cust_id)
                                            FROM   customer) )

所以。 . . 将发票金额设置为发票的发票项目的数量 * 价格之和。只需更新具有最新发票 ID 的发票记录,并且该最新发票是针对最新客户的。 这假设您正在使用序列创建 PK 值(发票应该采用最新的发票编号并添加 1)。其他的可能是简单的 Oracle 序列。 抱歉笨拙,但这里是虚拟星期五,我要回家了。

【讨论】:

  • 你是男人中的传奇。感谢您在虚拟星期五给我时间!
【解决方案2】:

您可以创建一个触发器来更新 invoice_ammount。像这样的:

CREATE OR REPLACE TRIGGER tg_invoice_item_amt 
  AFTER 
    DELETE OR 
    INSERT OR 
    UPDATE OF invoice_item_quantity, invoice_item_price
  ON invoice_item
  FOR EACH ROW
DECLARE
  l_change_amt NUMBER;
BEGIN
  CASE
    WHEN INSERTING THEN
      l_change_amt := COALESCE(:NEW.invoice_item_quantity * :NEW.invoice_item_price, 0);
    WHEN UPDATING THEN
      l_change_amt := COALESCE(:NEW.invoice_item_quantity * :NEW.invoice_item_price, 0) 
                      - COALESCE(:OLD.invoice_item_quantity * :OLD.invoice_item_price, 0);
    WHEN DELETING THEN
      l_change_amt := 0 - COALESCE(:OLD.invoice_item_quantity * :OLD.invoice_item_price, 0);
  END CASE;
  IF l_change_amt != 0 THEN
    UPDATE invoice SET invoice_amount = invoice_amount + l_change_amt;
END;
/

【讨论】:

    猜你喜欢
    • 2018-07-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多