PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Upsert avec une transaction

En supposant ce tableau simple :

CREATE TABLE tbl(id int primary key, value int);

Cette fonction presque 100 % sécurisé (voir commentaires) pour les transactions simultanées :

CREATE OR REPLACE FUNCTION f_upsert(_id int, _value int)
  RETURNS void AS
$func$
BEGIN
LOOP
   UPDATE tbl SET value = _value WHERE  id = _id;

   EXIT WHEN FOUND;

   BEGIN
      INSERT INTO tbl (id, value)
      VALUES (_id, _value);

      RETURN;

   EXCEPTION WHEN UNIQUE_VIOLATION THEN     -- tbl.id has UNIQUE constraint.
      RAISE NOTICE 'It actually happened!'; -- hardly ever happens
   END;

END LOOP;
END
$func$ LANGUAGE plpgsql;

Appel :

SELECT f_upsert(2, 2);

C'est très similaire à ce INSERT / SELECT cas avec plus d'explications et de liens :

  • SELECT ou INSERT est-il dans une fonction sujette à des conditions de concurrence ?