Penso che nella maggior parte dei casi le differenze tra i due saranno abbastanza piccole che la scelta dovrebbe essere guidata principalmente dalla scelta dell'implementazione che finisce per essere più comprensibile per qualcuno che guarda il codice per la prima volta.
Tuttavia, penso che la gestione delle eccezioni abbia alcuni piccoli vantaggi:
-
La gestione delle eccezioni evita una potenziale condizione di gara. Il metodo "controlla, quindi inserisci" potrebbe non riuscire se un altro processo inserisce un record tra il tuo controllo e il tuo inserto. Quindi, anche se stai eseguendo "controlla e poi inserisci", desideri comunque la gestione delle eccezioni sull'inserto e se stai già eseguendo comunque la gestione delle eccezioni, allora potresti anche eliminare il controllo iniziale.
-
Se il tuo codice non è una stored procedure e deve interagire con il database tramite la rete (cioè l'applicazione e il db non sono sulla stessa casella), allora vuoi evitare di avere due chiamate di rete separate (una per il check e la altro per l'inserto) e farlo tramite la gestione delle eccezioni fornisce un modo semplice per gestire l'intera operazione con una singola chiamata di rete. Ora, ci sono un sacco di modi per eseguire il metodo "controlla e poi inserisci" evitando comunque la seconda chiamata di rete, ma è probabile che la semplice cattura dell'eccezione sia il modo più semplice per farlo.
D'altra parte, la gestione delle eccezioni richiede un vincolo univoco (che in realtà è un indice univoco), che viene fornito con un compromesso sulle prestazioni:
- La creazione di un vincolo univoco sarà lenta su tabelle molto grandi e causerà un calo delle prestazioni su ogni singolo inserimento in quella tabella. Su database di grandi dimensioni è inoltre necessario prevedere un budget per lo spazio su disco aggiuntivo consumato dall'indice univoco utilizzato per applicare il vincolo.
- D'altra parte, potrebbe velocizzare la selezione dalla tabella se le tue query possono sfruttare tale indice.
Vorrei anche notare che se ti trovi in una situazione in cui ciò che vuoi effettivamente fare è "aggiornare altrimenti inserire" (cioè se esiste già un record con il valore univoco, vuoi aggiornare quel record, altrimenti inserisci un nuovo record) allora quello che vuoi effettivamente usare è il metodo UPSERT del tuo particolare database, se ne ha uno. Per SQL Server e Oracle, si tratterebbe di un'istruzione MERGE.