Jag tror att skillnaderna mellan dessa två i de flesta fall kommer att vara tillräckligt små för att valet främst ska styras av att välja den implementering som i slutändan blir mest förståelig för någon som tittar på koden för första gången.
Jag tror dock att undantagshanteringen har några små fördelar:
-
Undantagshantering undviker ett potentiellt tävlingstillstånd. Metoden 'check, then insert' kan misslyckas om en annan process infogar en post mellan din check och din insättning. Så även om du gör "kontrollera sedan infoga" vill du fortfarande ha undantagshantering på insatsen och om du ändå redan gör undantagshantering kan du lika gärna göra dig av med den första kontrollen.
-
Om din kod inte är en lagrad procedur och måste interagera med databasen via nätverket (dvs applikationen och db är inte på samma box), så vill du undvika att ha två separata nätverksanrop (ett för kontrollen och annat för insatsen) och att göra det via undantagshantering ger ett enkelt sätt att hantera det hela med ett enda nätverksanrop. Nu finns det massor av sätt att göra "kontrollera och infoga"-metoden samtidigt som du undviker det andra nätverksanropet, men att bara fånga undantaget är troligen det enklaste sättet att gå tillväga.
Å andra sidan kräver undantagshantering en unik begränsning (vilket egentligen är ett unikt index), som kommer med en prestandaavvägning:
- Att skapa en unik begränsning kommer att gå långsamt på mycket stora tabeller och det kommer att orsaka en prestandaträff på varje enskild insättning i den tabellen. På riktigt stora databaser måste du också budgetera för det extra diskutrymmet som förbrukas av det unika indexet som används för att upprätthålla begränsningen.
- Å andra sidan kan det gå snabbare att välja från tabellen om dina frågor kan dra nytta av det indexet.
Jag skulle också notera att om du är i en situation där det du faktiskt vill göra är att "uppdatera infoga annat" (dvs. om en post med det unika värdet redan finns så vill du uppdatera den posten, annars infogar du en ny record) så är det du faktiskt vill använda just din databas UPSERT-metod, om den har en. För SQL Server och Oracle skulle detta vara en MERGE-sats.