sql >> Databáze >  >> RDS >> PostgreSQL

Upsert s transakcí

Za předpokladu této jednoduché tabulky:

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

Tato funkce téměř 100% bezpečné (viz komentáře) pro souběžné transakce.:

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;

Volejte:

SELECT f_upsert(2, 2);

Je to velmi podobné tomuto INSERT / SELECT případ s dalším vysvětlením a odkazy:

  • Je SELECT nebo INSERT ve funkci náchylný k závodům?



  1. 2 způsoby, jak vrátit řádky, které obsahují pouze nealfanumerické znaky v Oracle

  2. PostgreSQL:sériové vs identita

  3. Zjistěte, proč se nepodařilo odeslat e-mail na SQL Server (T-SQL)

  4. Ukládá Oracle koncové nuly pro datový typ Number?