SQL触发器更新始终为空

时间:2016-11-25 07:08:18

标签: sql oracle plsql triggers

我们正试图根据租用天数来计算租车的TOTAL_COST。租赁的总成本根据车辆的天数和成本计算。总额中还增加了12%的额外税。如果租金超过10天,则从总费用中扣除15%的折扣。

这是我们的触发器:

create or replace trigger L5_Q8
    After Update on E2_RESERVATIONS
    for each row
    Declare
    TOTALDAYS NUMBER(4);
    TotalCostBeforeTax Number(8);
    BEGIN
    TOTALDAYS := (trunc(:NEW.END_DATE) - TRUNC(:NEW.START_DATE)) + 1;
    IF(TOTALDAYS > 10) THEN
      SELECT V.COST_PER_DAY * TOTALDAYS * 0.85
        INTO TotalCostBeforeTax
        from E2_Reservations R
        join E2_Vehicle V on R.V_ID = V.V_ID;
    END IF;
    IF(TOTALDAYS <= 10) THEN
       SELECT V.COST_PER_DAY * TOTALDAYS
        INTO TotalCostBeforeTax
        from E2_Reservations R
        join E2_Vehicle V on R.V_ID = V.V_ID;
    END IF;
      TotalCostBeforeTax := TotalCostBeforeTax * 1.12;
      UPDATE E2_RESERVATIONS SET TOTAL_COST =  10.1 WHERE ROWID IN (SELECT MAX(ROWID) FROM E2_RESERVATIONS);
    END; 

这些是我们的表:

E2_RESERVATIONS:

E2_RESERVATIONS Table

E2_VEHICLE:

Vehicle Table

1 个答案:

答案 0 :(得分:1)

您正在尝试计算当前记录的总费用,对吧?因此,在应用更改之前计算,而不是在after update触发器中。此外,该触发器中的SQL太多了。

试试这个:

create or replace trigger l5_q8
    before update on e2_reservations
    for each row
declare
    totaldays number(4);
    totalcostbeforetax number(8,2); 
begin
    -- length of reservation
    totaldays := (trunc(:new.end_date) - trunc(:new.start_date)) + 1;

    -- base cost of hire
    select v.cost_per_day * totaldays 
    into totalcostbeforetax
    from e2_vehicle v 
    where v.v_id = :new.v_id;

    -- apply discount for long reservation
    if(totaldays > 10) then
       totalcostbeforetax := totalcostbeforetax * 0.85;
    end if;

    -- apply tax to total cost
    :new.total_cost := totalcostbeforetax * 1.12;
end; 

请注意,这是一个BEFORE UPDATE触发器,而不是AFTER UPDATE。

此外,变量totalcostbeforetax需要处理小数,因为你乘以0.85,并且无论如何应该匹配列total_cost的声明。

  

“您是否需要加入车辆预订?”

触发器可以访问构建它的触发器的所有列。因此,您已经通过where v.v_id = :new.v_id加入了RESERVATIONS表,这是当前预订记录的车辆ID。