Actualizar los registros si existen

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 a 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;

PS ph.status tiene un tipo de varchar y no integer only for simplicity.

preguntado el 28 de mayo de 14 a las 11:05

2 Respuestas

1) Necesitas emitir the day count to an interval:

AND (ph.added_at + ($2 || ' days')::interval) <= now()

2) Puedes usar CURSORs 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 mando:

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()

contestado el 28 de mayo de 14 a las 12:05

Como agrego max_day_amount_allowed a ph.added_at?

Assuming the type timestamp para 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()

O si added_at es un date, solo puedes agregar integer a una date. The date is then coerced to timestamp automatically (according to locales time) for the comparison to now():

ph.added_at + max_day_amount_allowed <= now()

contestado el 30 de mayo de 14 a las 17:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.