1

我正在尝试计算一些值并将它们添加到另一个表中。

所以我有预订、治疗和发票。用户预订一些治疗,然后预订会话生成发票。我已经手动插入发票插入语句,只是尝试根据预订会话数填充计算值。附言。治疗价格在治疗表中。

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

4

1 回答 1

1

如果目标是使用在第二个查询中计算的特定更新列,INV_SUBTOTAL则需要一个语句。我的猜测(因为我不知道or表是什么样子或它们包含什么数据)是你想要一个看起来像的相关更新INVOICEINV_IDTOTALUPDATETREATMENTBOOKING_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也无法在BOOKING_SESSION不生成变异表异常的情况下查询表,我们几天前在您的一个问题中讨论了该异常。触发器中的:new记录基于定义触发器的表——您只能引用属于表的BOOKING_SESSION列。您无法引用:new.inv_subtotal,除非INV_SUBTOTAL是您在其上定义触发器的表中的列。

在现实世界中,这里也会存在严重的非规范化问题。TREATMENT将聚合数据与行级数据分开存储违反了基本规范化,并且几乎肯定会导致聚合数据与存储在表中的较低级别数据不匹配的数据质量问题。由于这只是一个家庭作业,也许你的教授希望你忽略这个问题,但这是你在现实世界中想要非常敏感的事情。

于 2012-11-19T21:09:09.897 回答