Reputation: 34884
Periodically I need to check the records in a table and update them, in particular check the records with "payment_pending
" status and update them to "payment_pending_expired
" status. But I'm not sure how to do it properly:
CREATE OR REPLACE FUNCTION cancel_pending_orders(user_id integer, max_day_amount_allowed integer)
RETURNS SETOF void AS
$BODY$
BEGIN
-- if the records exist at all...
IF EXISTS (
SELECT ph.id FROM payment_history as ph
INNER JOIN payment AS p
ON p.id = ph.payment_id
WHERE p.user_id = $1
AND ph.status = 'payment_pending'
AND ph.added_at + max_day_amount_allowed <= now()
) THEN
-- make all of them status = 'payment_pending_expired'
RETURN;
END IF;
The questions:
1) How do I add max_day_amount_allowed
to ph.added_at
? If it were a literal I could do this by:
....
AND (ph.added_at + interval '30d') <= now()
but it is not a literal, it is a variable.
2) How do I refer to the found records (in case, the exist)
....
) THEN
-- make all of them ph.status = 'payment_pending_expired'
-- but how do I refer to them?
RETURN;
P.S. ph.status
has a type of varchar
and not integer
only for simplicity.
Upvotes: 0
Views: 67
Reputation: 656321
How do I add
max_day_amount_allowed
toph.added_at
?
Assuming the type timestamp
for added_at
.
Don't convert to text
, concatenate and convert back. Just multiply an interval
:
ph.added_at + interval '1d' * max_day_amount_allowed <= now()
Or, if added_at
is a date
, you can just add integer
to a date
. The date is then coerced to timestamp automatically (according to local time) for the comparison to now()
:
ph.added_at + max_day_amount_allowed <= now()
Upvotes: 1
Reputation: 36214
1) You need to cast the day count to an interval:
AND (ph.added_at + ($2 || ' days')::interval) <= now()
2) You can use CURSOR
s to do something with each row in a result-set.
But in your case (if you want to only update them) just use a single UPDATE
command:
UPDATE payment_history AS ph
SET ph.status = 'payment_pending_expired'
FROM payment AS p
WHERE p.id = ph.payment_id
AND p.user_id = $1
AND ph.status = 'payment_pending'
AND (ph.added_at + ($2 || ' days')::interval) <= now()
Upvotes: 2