2013-03-29 13 views
21

Sto scrivendo una procedura di prenotazione per un database di prenotazione aerea finta e quello che voglio fare è qualcosa di simile:INSERT INTO condizionale in postgres

IF EXISTS (SELECT * FROM LeadCustomer 
    WHERE FirstName = 'John' AND Surname = 'Smith') 
THEN 
    INSERT INTO LeadCustomer (Firstname, Surname, BillingAddress, email) 
    VALUES ('John', 'Smith', '6 Brewery close, 
      Buxton, Norfolk', [email protected]'); 

Ma Postgres non supporta IF dichiarazioni senza caricamento dell'estensione PL/pgSQL. Mi stavo chiedendo se ci fosse un modo per fare qualcosa di equivalente o se ci dovesse essere qualche interazione con l'utente in questo passaggio?

+0

Perché non caricare semplicemente l'estensione PL/pgSQL, quindi? –

+0

@MattBall: utilizzo dell'installazione di postgres sui computer di laboratorio. L'utilizzo di tale estensione non è nelle specifiche. –

risposta

45

Questo comando specifico può essere fatto in questo modo:

insert into LeadCustomer (Firstname, Surname, BillingAddress, email) 
select 
    'John', 'Smith', 
    '6 Brewery close, Buxton, Norfolk', '[email protected]' 
where not exists (
    select * from leadcustomer where firstname = 'John' and surname = 'Smith' 
); 

Sarà inserire il risultato della dichiarazione prescelta, e il select tornerà solo una fila se quel cliente non esiste.

+1

Suppongo che ci sia una (molto piccola) razza qui? La sottoquery selezionata viene eseguita, restituisce 0 righe, un inserto si verifica in un altro thread e quindi si verifica l'inserimento di LeadCustomer? –

+0

@Kevin Sarà sollevata un'eccezione della chiave primaria e l'applicazione deciderà cosa fare. –

+1

Sono confuso, la domanda non menziona le chiavi primarie ovunque. Se era presente una chiave primaria (nome, cognome), perché non dovresti provare prima l'inserto? –

1

partire dalla 9.5 versione di pgsql upsert è incluso, usando INSERT ... ON CONFLICT DO UPDATE ...

La risposta qui sotto non è più rilevante. Postgres 9.5 è stato rilasciato un paio d'anni dopo con una soluzione migliore.

Postgres non ha la funzionalità "upsert" senza aggiungere nuove funzioni.
Quello che dovrete fare è eseguire la query di selezione e vedere se avete righe corrispondenti. Se lo fai, quindi inseriscilo.

So che non vuoi esattamente un upsert, ma è praticamente lo stesso.

+0

C'è un modo per farlo: http://stackoverflow.com/a/8702291/330315 –

+0

questo continuerà ad aumentare l'ID auto incrementato anche quando c'è un conflitto (come si tenta di inserire) – rohanagarwal

+0

"Controllare i risultati, inserire condizionatamente "è soggetto a condizioni di gara: se hai due thread contemporaneamente, puoi ottenere due inserimenti. –

Problemi correlati