'Logical problems in SQL procedure

I'm writing a procedure that is supposed to do the following:

  • Create a procedure that adds item (s) to an order.
  • The number of what is in stock for the item must also be reduced by the same number.
  • If no_of_items are more than what is in stock, the highest possible should be added so that stock is zero.
  • The procedure must respond with a status of how many items have been added and warn or inform if the number was not as many as desired.
  • If there are no items in stock, information must also be provided.
  • Check must also be done so that the order ID and item ID are available.
  • It should only be possible to add items to an order if it has shipping_status set to "open".

The procedure I have written looks as following:

    DELIMITER //
CREATE PROCEDURE add_item_to_order(order_id INT, item_id INT, no_of_items INT)
BEGIN
IF order_id IN (SELECT number FROM Orders WHERE Orders.status = "open")  THEN
IF item_id IN (SELECT number FROM Items WHERE Items.stock = 0) THEN
    SIGNAL SQLSTATE "45000" SET MESSAGE_TEXT = "item is not in stock";
    END IF;
    SET @stock = (SELECT Items.stock FROM Items WHERE Items.number = item_id);
 IF no_of_items <= @stock  THEN
 WHILE no_of_items > 0 DO
    INSERT INTO orders_items (o_id, i_id) VALUES (order_id, item_id);
    UPDATE Items SET Items.stock = (Items.stock - no_of_items) WHERE Items.number = item_id;
    SET no_of_items = no_of_items - 1;
    END WHILE;
    SELECT (no_of_items) AS "Item has been added. Amount of items: " ;
    END IF;
IF no_of_items > @stock THEN
 WHILE no_of_items > 0 DO
    INSERT INTO orders_items (o_id, i_id) VALUES (order_id, item_id - (item_id * no_of_items));
    UPDATE Items SET Items.stock = (Items.stock - no_of_items) WHERE Items.number = item_id;
    SET no_of_items = (no_of_items -1);
    END WHILE;
    SIGNAL SQLSTATE "45000" SET MESSAGE_TEXT = "Enough is not in stock. Biggest possible amount of items has been added" ;
    END IF;
ELSE SIGNAL SQLSTATE "45000" SET MESSAGE_TEXT = "Order must have status Open";
END IF;    
END //
DELIMITER ;

The problem is that somethings are logically wrong because the output is not as expected. If I try to call it with: CALL add_item_to_order(7, 5, 2), it should add two rows because no_of_items are 2, but it only adds one row. I need help with figuring out how I should write instead so it gives the correct output.

Also, if anyone has advice on how I can improve this query, I would very much appreciate it. I have written this procedure for a couple of days and can't figure out if its good written or bad.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source