Question

I need to create a trigger that modifies insert statements to allow the insertion of x numbers of soccer balls into my table. So for example I can only have a max of 7 soccer balls that are checked out and my goal is to have the trigger reduce the quantity in the insert statement to allow it to be inserted. This is my table:

highlineitem
(item_id varchar2(7) not null,
quantity number not null,
description varchar2(30),
dateout date,
datein date,
captain_id number
);

and this is my trigger so far...it works for when I insert rows with quantities of: 1,1,2,4...the 4 will be reduced to 3 and the insert statement will be inserted totaling out to a maximum quantity of 7 which is what I want it to do...HOWEVER..when I delete from highlineitem and no records are left...I tried testing it out with one insert row with the quantity value of 8...thats when it doesnt trigger the reduction...any ideas??? my code is this:

UPDATED!! THIS SHOULD BE THE CORRECT CODE...I WAS MISSING AN ELSIF STATEMENT..

create or replace trigger highlineitem_bef_ins_row
before insert on highlineitem for each row
declare
    checked_out_so_far  number :=0;
    total           number :=0;
    hold            number :=0;
    error_message       exception;
begin
    --dbms_output.put_line('TOTAL');
    if :new.description = 'Soccer Ball' then
        --dbms_output.put_line('If statement executed.');
        SELECT SUM(QUANTITY) INTO CHECKED_OUT_SO_FAR FROM HIGHLINEITEM
        WHERE CAPTAIN_ID = :NEW.CAPTAIN_ID
        AND DESCRIPTION = 'Soccer Ball';
        --dbms_output.put_line('CHECKED_OUT_SO_FAR' || ' ' || checked_out_so_far);
        TOTAL := CHECKED_OUT_SO_FAR + :NEW.QUANTITY;
        HOLD := :NEW.QUANTITY;
        --dbms_output.put_line(TOTAL);
        if TOTAL > 7 then
            :NEW.QUANTITY :=7 - CHECKED_OUT_SO_FAR;
            dbms_output.put_line('Your insert statement was revised to allow '|| :NEW.QUANTITY || ' Soccer Balls to be checked out.');
        elsif :NEW.QUANTITY > 7 then
            :NEW.QUANTITY := 7- :NEW.QUANTITY + :NEW.QUANTITY;
            dbms_output.put_line('Your insert statement was revised to allow '|| :NEW.QUANTITY || ' Soccer Balls to be checked out.');
        end if;
    end if;

END;
/
Was it helpful?

Solution

Your trigger appears to work fine, if there's already data in the table:

SQL> insert into highlineitem (item_id, quantity, description, captain_id) values (1, 1, 'Soccer Ball', 1);

1 row created.

SQL> insert into highlineitem (item_id, quantity, description, captain_id) values (2, 8, 'Soccer Ball', 1);
Your insert statement was revised to allow 6 Soccer Balls to be checked out.

1 row created.

The problem is if there isn't already any data in this table:

SQL> delete from highlineitem;

2 rows deleted.

SQL> insert into highlineitem (item_id, quantity, description, captain_id) values (3, 999, 'Soccer Ball', 1);

1 row created.

The reason this happens is because a SUM of no data is NULL, not zero. Arithmetic operations involving NULL return NULL, so your variable TOTAL contains NULL, and as NULL is not greater than 7, the quantity doesn't get altered.

The fix is fairly simple: replace SUM(QUANTITY) with NVL(SUM(QUANTITY), 0).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top