wstawianie rekordu, gdy jeszcze go nie ma

kolega z pracy zapytał:

jak wstawić rekord do tabelki, ale tylko jeśli go tam jeszcze nie ma?

teoretycznie sprawa jest prosta: select, jak nic nie zwróci – insert. no ale jak będzie to działało równolegle to jest spora szansa na wysypanie się takiego kodu.

potrzebna jest więc inna metoda.

może insert i przechwycenie błędu.

w sumie to nie takie głupie:

  • BEGIN;
  • INSERT;
  • COMMIT;

jeśli insert się nie udał, no to commit zrobi to samo co rollback.

fajnie. zadziała. ale jest jakoś mało eleganckie.

a może inaczej … chwila zastanowienia i … jest. proste rozwiązanie:

INSERT INTO tabelka (pole_1, pole_2, …, pole_n)
SELECT wartosc_1, wartosc_2, …, wartosc_n
WHERE NOT EXISTS ( SELECT * FROM tabelka WHERE pole_1 = wartosc_1 AND pole_2 = wartosc_2 AND … AND pole_n = wartosc_n);

nie jest to może najśliczniejsze, ale działa na pewno. nie wywala się niezależnie od tego czy wstawiło czy nie (więc można bezpiecznie używać w transakcjach). same plusy 🙂