Search code examples
oracle-databasestored-proceduresplsqlcursororacle-apex

My shopping cart procedure with cursor is throwing errors


I have a group project in which we are creating a shopping cart application. I got some feedback and fixed it, turning it into a procedure with a cursor. However, we are still getting errors that I do not know how to fix, such as trying to put a null value into a table column that cannot be null. I do not know why it thinks I am trying to input a null value. Our project is due tomorrow so please help!

I tried it as a trigger at first but it was not working so it was suggested to turn it into a procedure with cursor so I did that.

create or replace PROCEDURE CANCELCART (arg_cart_id IN number)

IS
ws_prod_id number;
ws_item_quantity_in_cart number;
ws_cart_id number;
ws_cart_status char;

cursor cancel IS
select item_product_id, item_quantity_in_cart
FROM sc_items i
WHERE item_cart_id = arg_cart_id
group by item_product_id;

alreadycancelled exception;

BEGIN
select max(cart_id) into ws_cart_id
from sc_cart
where arg_cart_id = cart_id;

/*cart check*/
select max(cart_status) into ws_cart_status
from sc_cart
where arg_cart_id = cart_id;

if ws_cart_id is null
    then raise alreadycancelled;
    end if;

open cancel;
LOOP
fetch cancel into ws_prod_id, ws_item_quantity_in_cart;
    UPDATE sc_product p SET prod_quan_avail = prod_quan_avail + ws_quantity_in_cart, 
    prod_quan_sold = prod_quan_sold - ws_quantity_in_cart
    WHERE prod_id = ws_prod_id;
    DELETE FROM sc_items i WHERE i.item_cart_id = arg_cart_id;
END LOOP;
close cancel;

DELETE FROM sc_cart c WHERE c.cart_id = arg_cart_id;

EXCEPTION
when alreadycancelled 
    then raise_application_error(-20400, 'Cart does not exist');

END;

I need this code to cancel a shopping cart and return all of the item quantities back to the original stock.


Solution

  • There's no much missing part for your code block, except define ws_quantity_in_cart variable with a data type, and add more handling for other type of exceptions than which's already included (ORA-20400)

    CREATE OR REPLACE PROCEDURE CANCELCART( arg_cart_id sc_cart.cart_id%type ) IS
        ws_prod_id               sc_product.prod_id%type;
        ws_item_quantity_in_cart sc_product.prod_quan_avail%type;
        ws_cart_id               sc_cart.cart_id%type;
        ws_cart_status           sc_cart.cart_status%type;
        ws_quantity_in_cart      sc_product.prod_quan_sold%type;
    
        cursor cancel IS
        select item_product_id, item_quantity_in_cart
          from sc_items i
         where item_cart_id = arg_cart_id
         group by item_product_id;
    
        alreadycancelled exception;
    
    BEGIN
        select max(cart_id)
          into ws_cart_id
          from sc_cart
         where arg_cart_id = cart_id;
    
        /*cart check*/
        select max(cart_status)
          into ws_cart_status
          from sc_cart
         where arg_cart_id = cart_id;
    
        if ws_cart_id is null
            then raise alreadycancelled;
            end if;
    
        open cancel;
        loop
        fetch cancel into ws_prod_id, ws_item_quantity_in_cart;
            update sc_product p 
               set prod_quan_avail = prod_quan_avail + ws_quantity_in_cart,
                   prod_quan_sold = prod_quan_sold - ws_quantity_in_cart
             where prod_id = ws_prod_id;
            delete sc_items i where i.item_cart_id = arg_cart_id;
        end loop;
        close cancel;
    
        delete sc_cart c where c.cart_id = arg_cart_id;
    
     exception when alreadycancelled  then raise_application_error(-20400, 'Cart does not exist');
               when      others       then raise_application_error(SQLCODE,SQLERRM);
    
    END;
    

    Prefer Using column's original data types by <table_name>.<column_name>.%type to define the data types of variables, and never use fixed-length string-type variable of type char, use varchar2 instead.