i’m practicing with this stored procedure on a MYSQL database to make payments between accounts. it takes inputs of two accounts(acct1, acct2), an amount(amt) to be paid and outputs a confirmation message(pmessage)
it’s supposed to make payment only when: (IF (balance1 >=amt) THEN …), but somehow when i input any amount greater than the available balance, it still goes ahead to make payment. i don’t understand. pls help.
here’s the code:
DELIMITER //
CREATE PROCEDURE `make_payment`(IN `acct1` int(4), IN `acct2` int(4), IN `amt` float(10,2) unsigned, OUT `pmessage` varchar(100))
BEGIN
DECLARE balance1 FLOAT;
DECLARE balance2 FLOAT;
IF(acct1 !=acct2) THEN
SELECT balance INTO balance1 FROM mydb.accounts
WHERE account_no =acct1
ORDER BY balance DESC LIMIT 1;
SELECT balance INTO balance2 FROM mydb.accounts
WHERE account_no =acct2
ORDER BY balance DESC LIMIT 1;
IF (balance1 >=amt) THEN
begin
SET balance1 =balance1-amt;
SET balance2 =balance2+amt;
INSERT INTO mydb.accounts(account_no, outflow, balance)
VALUES(acct1, amt, balance1);
INSERT INTO mydb.accounts(account_no, inflow, balance)
VALUES(acct2, amt, balance2);
SET pmessage ="payment was successful";
END;
ELSE SET pmessage ="insufficient balance";
END IF;
END IF;
END //
DELIMITER ;
(Upgrading to an answer)
You’re ordering the
accountstable bybalancein descending order, therefore you’re assuming that the “available balance” is the greatest balance for the given account in that table. You want instead toORDER BYdate and select the most recent record.Please also note the other points made in my comment above, including:
You ought to be using fixed-point datatypes (such as
DECIMAL) for currency, instead of floating-point types; andYou ought to perform these actions in a transaction to prevent concurrency issues.