我需要定期检查表中的记录并更新它们,特别是用" payment_pending
"检查记录。状态并将其更新为" payment_pending_expired
"状态。但我不确定如何正确地做到这一点:
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;
问题:
1)如何将max_day_amount_allowed
添加到ph.added_at
?如果它是文字,我可以通过以下方式完成:
....
AND (ph.added_at + interval '30d') <= now()
但它不是文字,而是变量。
2)我如何参考找到的记录(如果存在)
....
) THEN
-- make all of them ph.status = 'payment_pending_expired'
-- but how do I refer to them?
RETURN;
P.S。 <{1}}的类型只有ph.status
而不是varchar
,只是为了简单起见。
答案 0 :(得分:2)
1)您需要将cast日计为间隔时间:
AND (ph.added_at + ($2 || ' days')::interval) <= now()
2)您可以使用CURSOR
对结果集中的每一行执行某些操作。
但在你的情况下(如果你只想更新它们)只需使用一个UPDATE
命令:
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()
答案 1 :(得分:1)
如何将
max_day_amount_allowed
添加到ph.added_at
?
假设timestamp
的类型为 added_at
。
不要转换为text
,连接并转换回来。只需乘以interval
:
ph.added_at + interval '1d' * max_day_amount_allowed <= now()
或者,如果added_at
是 date
,您只需将integer
添加到date
即可。然后,日期会自动强制为时间戳(根据本地时间),以便与now()
进行比较:
ph.added_at + max_day_amount_allowed <= now()