Database Reference
In-Depth Information
There's more...
Move the whole computation into the database function
If you can pass all the needed information into the database for processing as a database
function, it will run even faster, as you save several roundtrips to database. If you use a PL/
pgSQL function, you also benefit from automatically saving query plans on first call in a
session, and using saved plans in subsequent calls.
So the preceding transaction is replaced by a function in the database as follows:
CREATE OR REPLACE FUNCTION consume_balance (
i_username text, i_amount numeric(10,2), max_credit numeric(10,2),
OUT success boolean, OUT remaining_balance numeric(10,2)) AS
$$
BEGIN
UPDATE accounts SET balance = balance - i_amount
WHERE username = i_username
AND balance - i_amount > - max_credit
RETURNING balance
INTO remaining_balance;
IF NOT FOUND THEN
success := FALSE;
SELECT balance
FROM accounts
WHERE username = i_username
INTO remaining_balance;
ELSE
success := TRUE;
END IF;
END;
$$ LANGUAGE plpgsql;
and you call it simply by running:
SELECT * FROM consume_balance ('bob', 7, 0);
from your client, returning the success variable telling you if there was high enough balance in
Bob's account, and the number telling the balance Bob has left after this operation.
 
Search WWH ::




Custom Search