2017-04-13 67 views
0

我创建一个包含四个不同表的数据库:Oracle事务更新量从一个表到另一个

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)。

我能做到这一切,而不使用INSERT命令的任何问题,但下一步是绊倒了我,让

“更新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

但我不能得到这个代码的任何变化工作。我确信有一些非常简单的答案,会让我感到很蠢,但如果有人能够帮助,我会非常感激。

+0

对我来说,INVOICE_AMOUNT应该是'总和(invoice_Item.Invoice_Item_Price * Invoice_Item_Quantity)'所以你需要获得和确保它不是空(或者其无效,至少使其0) – xQbert

+0

我也知道这一点,但在我的任务中注意到:您是否应该有一个INVOICE_AMOUNT字段值得怀疑,因为您始终可以查询INVOICE_ITEM表并为每个发票项目总结INVOICE_ITEM_QTY * INVOICE_ITEM_PRICE。但是,对于这项任务,我们假设我们想要这样做。 – CBevs

+0

相似问题:http://stackoverflow.com/questions/2446764/update-statement-with-inner-join-on-oracle – xQbert

回答

0

这可能有点笨重,但是考虑到你有什么并且没有指出那时使用了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)) 

所以。 。 。将发票金额设置为发票发票项目的数量*价格之和。只需更新具有最新发票编号的发票记录,并且该最新发票是针对最新客户的。 这假设您使用序列创建PK值(发票应该取最新的发票号码并将其加1)。其他可能是简单的Oracle序列。 对不起,但它是一个虚拟的星期五在这里,我即将回家。

+0

你是男人中的传奇人物。感谢您在虚拟的星期五给我你的时间! – CBevs

0

您可以创建一个将更新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; 
/