2012-11-19 117 views
1

我想計算一些值並將它們添加到另一個表中。Oracle:計算並插入到其他表觸發器/程序

所以我有預約,治療和發票。用戶預訂一些處理,然後預訂會話生成發票。我已經手動發票插入語句,只是試圖根據預訂會話的數量填充計算的值。 PS。治療價格在治療表中。

SQL> SELECT * FROM INVOICE; 

    INV_ID|INV_DATETIME     |INV_SUBTOTAL|INV_DISCOUNT| INV_TOTAL 
----------|------------------------------|------------|------------|----------- 
     100|14-NOV-12 09.40.06.918000  |  $.00|  $.00|  $.00 
     101|18-MAR-12 10.03.00.000000  |  $.00|  $.00|  $.00 
     102|18-MAR-12 10.15.00.000000  |  $.00|  $.00|  $.00 
     103|18-MAR-12 10.55.00.000000  |  $.00|  $.00|  $.00 
     104|18-MAR-12 10.38.00.000000  |  $.00|  $.00|  $.00 
     105|12-JUN-12 15.15.00.000000  |  $.00|  $.00|  $.00 
     106|06-AUG-12 12.13.00.000000  |  $.00|  $.00|  $.00 
     107|04-MAY-12 09.15.00.000000  |  $.00|  $.00|  $.00 
     108|29-NOV-12 13.16.00.000000  |  $.00|  $.00|  $.00 
     109|18-MAR-12 10.37.00.000000  |  $.00|  $.00|  $.00 
     110|21-MAR-12 11.26.00.000000  |  $.00|  $.00|  $.00 
     111|24-APR-12 11.16.00.000000  |  $.00|  $.00|  $.00 
     112|12-MAY-12 10.27.00.000000  |  $.00|  $.00|  $.00 
     113|21-MAY-12 13.33.00.000000  |  $.00|  $.00|  $.00 
     114|18-JAN-12 12.17.00.000000  |  $.00|  $.00|  $.00 
     115|20-JUN-12 11.18.00.000000  |  $.00|  $.00|  $.00 
     116|09-JUN-12 10.14.00.000000  |  $.00|  $.00|  $.00 

所以我用下面的SQL查詢來計算總價格爲發票多達預訂會議可以一次黃牌警告,這些都會出現在同一張發票上*。1

SQL> COLUMN total FORMAT $99,999.99 
SQL> SELECT IV.INV_ID, SUM(TR.TR_PRICE) as Total 
    2 FROM BOOKING_SESSION BS, TREATMENT TR, INVOICE IV 
    3 WHERE BS.INV_ID = IV.INV_ID 
    4 AND BS.BK_TREATMENT = TR.TR_ID 
    5 GROUP BY IV.INV_ID 
    6 ORDER BY BS.INV_ID ASC; 

    INV_ID|  TOTAL 
----------|----------- 
     100| $605.00 
     101|  $45.00 
     102|  $70.00 
     103|  $65.00 
     104|  $50.00 
     105|  $25.00 
     106|  $25.00 
     107|  $25.00 
     108|  $25.00 
     109|  $50.00 
     110|  $25.00 
     111|  $50.00 
     112|  $15.00 
     113|  $15.00 
     114|  $25.00 
     115|  $25.00 
     116|  $25.00 

現在我想抓住每個值並將其添加到INV_SUBTOTAL

我試着做了以下,但似乎沒有工作。

CREATE OR REPLACE TRIGGER INV_SUBTOTAL 
BEFORE INSERT OR UPDATE ON BOOKING_SESSION 
FOR EACH ROW 
BEGIN 
    SELECT 
     (SELECT SUM(TR.TR_PRICE) FROM BOOKING_SESSION BS, TREATMENT TR, INVOICE IV WHERE BS.INV_ID = IV.INV_ID AND BS.BK_TREATMENT = TR.TR_ID) 
     INTO :NEW.INV_SUBTOTAL 
    FROM DUAL; 
END; 
/

警告:使用編譯錯誤創建觸發器。

SQL> SHOW ERROR 
Errors for TRIGGER INV_SUBTOTAL: 

LINE/COL|ERROR 
--------|----------------------------------------------------------------- 
4/12 |PLS-00049: bad bind variable 'NEW.INV_SUBTOTAL' 
SQL> 

也許是我做錯了T_T

下面是關於表中的數據;

SQL> select * from treatment; 

    TR_ID|TR_NAME    |TR_SPECIALIST| TR_PRICE 
----------|--------------------|-------------|----------- 
     1|Hair removal  |   1|  $25.00 
     2|Hair styling  |   1|  $50.00 
     3|Nails    |   1|  $15.00 
     4|Botox    |   1|  $30.00 
     5|Make up    |   5|  $35.00 
     6|Reflexology   |   3|  $25.00 
     7|Massage therapy  |   3|  $25.00 
     8|Facial care   |   4|  $25.00 
     9|Weight loss   |   2|  $40.00 
     10|Consultation  |   2|  $20.00 

10 rows selected. 

SQL> select * from booking_session 
    2 where inv_id > 100; 

    BK_ID|BK_DATE      | BK_BOOKER|BK_CUSTOMER|BK_TREATMENT|START_SESSION    |END_SESSION    |STAFFAPPOINTED| BK_ROOM| INV_ID 
----------|------------------------------|----------|-----------|------------|------------------------------|------------------------------|--------------|----------|---------- 
     4|18-MAR-12 10.35.00.000000  |   1|   4|   10|20-MAR-12 12.00.00.000000  |20-MAR-12 13.00.00.000000  |    1|   4|  109 
     5|18-MAR-12 10.36.00.000000  |   1|   4|   4|21-MAR-12 11.00.00.000000  |20-MAR-12 12.00.00.000000  |    1|   5|  109 
     6|18-MAR-12 10.50.00.000000  |   5|   5|   2|20-MAR-12 11.00.00.000000  |20-MAR-12 12.00.00.000000  |    5|   6|  103 
     11|18-MAR-12 10.09.00.000000  |  10|   10|   10|20-MAR-12 11.00.00.000000  |20-MAR-12 12.00.00.000000  |   10|  10|  102 
     12|18-MAR-12 10.12.00.000000  |  10|   10|   6|22-MAR-12 11.00.00.000000  |22-MAR-12 12.00.00.000000  |   11|  11|  102 
     16|18-MAR-12 10.00.00.000000  |  15|   14|   10|20-MAR-12 11.00.00.000000  |20-MAR-12 12.00.00.000000  |   15|  14|  101 
     17|18-MAR-12 10.02.00.000000  |  15|   14|   7|20-MAR-12 12.00.00.000000  |20-MAR-12 13.00.00.000000  |   16|  15|  101 
     31|21-MAR-12 11.25.00.000000  |   1|   4|   1|24-MAR-12 11.00.00.000000  |24-MAR-12 12.00.00.000000  |    2|   1|  110 
     32|24-APR-12 11.15.00.000000  |   1|   4|   2|26-APR-12 12.00.00.000000  |26-APR-12 13.00.00.000000  |    3|   2|  111 
     33|12-MAY-12 10.25.00.000000  |   1|   4|   3|21-MAY-12 13.00.00.000000  |21-MAY-12 14.00.00.000000  |    4|   3|  112 
     34|21-MAY-12 13.32.00.000000  |   1|   4|   3|26-MAY-12 15.00.00.000000  |26-MAY-12 16.00.00.000000  |    4|   3|  113 
     35|18-JAN-12 12.14.00.000000  |   1|   4|   6|21-JAN-12 11.00.00.000000  |21-JAN-12 12.00.00.000000  |   17|   5|  114 
     36|20-JUN-12 11.16.00.000000  |   1|   4|   7|25-JUN-12 11.00.00.000000  |25-JUN-12 12.00.00.000000  |   22|   5|  115 
     37|09-JUN-12 10.12.00.000000  |   1|   4|   8|11-JUL-12 11.00.00.000000  |11-JUL-12 12.00.00.000000  |   24|   5|  116 
     20|18-MAR-12 10.30.00.000000  |  15|   17|   7|20-MAR-12 09.00.00.000000  |20-MAR-12 10.00.00.000000  |   16|  17|  104 
     39|18-MAR-12 10.35.00.000000  |   1|   17|   8|25-MAR-12 13.00.00.000000  |25-MAR-12 14.00.00.000000  |   24|   5|  104 
     40|12-JUN-12 15.11.00.000000  |   1|   17|   8|11-JUL-12 11.00.00.000000  |11-JUL-12 12.00.00.000000  |   24|   5|  105 
     41|06-AUG-12 12.13.00.000000  |   1|   17|   8|11-AUG-12 11.00.00.000000  |11-AUG-12 12.00.00.000000  |   24|   5|  106 
     42|04-MAY-12 09.15.00.000000  |   1|   17|   8|28-JUN-12 11.00.00.000000  |28-JUN-12 12.00.00.000000  |   24|   5|  107 
     43|29-NOV-12 13.16.00.000000  |   1|   17|   8|01-DEC-12 11.00.00.000000  |01-DEC-12 12.00.00.000000  |   24|   5|  108 
     44|18-MAR-12 10.53.00.000000  |   5|   5|   3|20-MAR-12 13.00.00.000000  |20-MAR-12 14.00.00.000000  |    6|   7|  103 
     38|18-MAR-12 10.13.00.000000  |   1|   10|   8|25-MAR-12 12.00.00.000000  |25-MAR-12 13.00.00.000000  |   24|   5|  102 

以下是與此問題相關的ERD的位。

erd2

回答

1

如果目標是爲特定INV_ID與在第二個查詢計算的TOTAL更新INVOICEINV_SUBTOTAL列,那麼你需要一個UPDATE聲明。我的猜測(因爲我不知道是什麼TREATMENTBOOKING_SESSION表的樣子還是什麼數據他們包含)是你想有一個相關的更新,看起來像

UPDATE invoice inv 
    SET inv_subtotal = (SELECT SUM(tr.tr_price) 
         FROM treatment tr, 
           booking_session bs 
         WHERE bs.inv_id = inv.inv_id 
          AND bs.bk_treatment = tr.tr_id) 

BOOKING_SESSION觸發不會做任何事情除非你實際更新(或插入)BOOKING_SESSION表。一般來說,BOOKING_SESSION的行級觸發器也不能在不產生mutating table exception的情況下查詢BOOKING_SESSION表,前兩天我們在其中一個問題中討論了它。而且觸發器中的記錄基於觸發器定義的表格 - 您只能引用屬於BOOKING_SESSION表的一部分的列。您不能引用:new.inv_subtotal,除非INV_SUBTOTAL是您定義觸發器的表中的一列。

在現實世界中,這裏也會出現嚴重的非規範化問題。與行級別數據分開存儲彙總數據違反了基本規範化,並且幾乎肯定會導致數據質量問題,其中彙總數據與TREATMENT表中存儲的較低級別數據不匹配。由於這只是一項家庭作業,也許你的教授希望你忽略這個問題,但這是你想在現實世界中非常敏感的事情。

+0

嗨賈斯汀,似乎我的老師從來沒有提到過這類問題,你剛纔提到的讓我意識到我的分貝問題,如果治療方法的價格發生變化,那麼發票也會改變,這是一個問題,因爲我們不會想要改變客戶實際支付的歷史用途和數據一致性。 那麼我的問題是,計算髮票的更好方法是什麼? –

+0

由於發票中的值應自動更新,因此創建觸發器會更好,因此在創建或編輯新預訂時,它會插入/更新發票表中的記錄? –

+0

@JoseDavidGarciaLlanos - 在現實世界中,最好的方式取決於。通常情況下,你根本不會在任何地方存儲總量。您將創建一個計算髮票金額的函數(通過合計「tr.tr_price」行)並使用它。如果要存儲發票金額,則應存儲實際發送的發票金額,即使所有處理的價格都發生變化,您仍希望該發票金額保持不變。當然,這意味着您希望總結和詳細信息不同步。 –