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 🙂

9 thoughts on “wstawianie rekordu, gdy jeszcze go nie ma”

  1. Moze troche nie w temacie, ale ostatnio czytalem Pana tekst o implementacji drzewek w sql. Czy byla by mozliwosc zeby Pan przeslal mi ten tekst ? Pozdrawiam

  2. I znów w MySQL można zrobić to prościej i ładniej. Przede wszystkim polecałbym założyć klucz unikalny na pole, które ma być decydujące o tym, czy rekord jest czy nie. Następnie kwestia prosta: INSERT IGNORE.

    Inną fajną sprawą jest polecenie INSERT … ON DUPLICATE KEY UPDATE. Powoduje, że jeśli rekordu nie ma, to go dodajemy. A jeśli jest, to aktualizujemy. Fajne, nie?

    No i last but not least, jest polecenie SELECT … FOR UPDATE, które też jest przydatne w określonych przypadkach.

  3. premax. chcialbym bys zwrocil uwage, ze ja nie pisze o:
    1. myslq jest kijowy
    2. postgresql kontra reszta swiata.
    3. bazach ogolnie.
    pisze o postgresie. tylko o postgresie. jak zaczne pisac o mysqlu, to bede ci wdzieczny za komentarze o mysql’u. ale na razie sa one troche nie na miejscu.
    i cieszy mnie niezmiernie, ze cos takiego mozna prosto zrobic w mysql’u. tylko dlaczego tak straszliwie na sile ewangelizujesz?

  4. mam nadzieje, ze sie nie obrazasz. lubie komentarze – jakbym nie lubil to byl nie robil bloga tylko site w stylu paula grahama.
    ale twoje komentarze wydaja mi sie byc mocno ewangelizujace. nie mam nic przeciwko mysql’owi. po prostu go nie uzywam. tak jak nie uzywam firebirda, oracle’a, db2, sybase’a i innych baz. znam, lubie i uzywam postgresql’a.

  5. Wiekszość postgresowców właśnie toczy świętą wojnę z MySQL, choć posiada o nim jeśli nie zerową wiedzę, to w najlepszym wypadku wiedzę na poziomie v więć może jestem troche przeczulony. Przy okazji, pisałeś na niusach, że znasz wady Postgresa. Może byś je tu lub tam wymienił, miałbym więcej argumentów do obrony :>

  6. > Może byś je tu lub tam wymienił, miałbym więcej argumentów do obrony :>

    pomagać “przeciwnikowi”? eee. tak się nie godzi.
    a poważniej.
    za jakiś czas napiszę coś więcej o problemach postgresa. ale nie obiecuje kiedy.

Comments are closed.