Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

AGGIORNAMENTO se esiste altro INSERT in SQL Server 2008

Molte persone ti suggeriranno di utilizzare MERGE , ma ti avverto di non farlo. Per impostazione predefinita, non ti protegge dalla concorrenza e dalle condizioni di gara non più di più dichiarazioni, ma introduce altri pericoli:

  • Utilizzare Attenzione con l'istruzione MERGE di SQL Server
  • Cosa evitare se si desidera utilizzare MERGE
  • Pattern e antipattern UPSERT di SQL Server

Anche con questa sintassi "più semplice" disponibile, preferisco comunque questo approccio (gestione degli errori omessa per brevità):

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
UPDATE dbo.table SET ... WHERE PK = @PK;
IF @@ROWCOUNT = 0
BEGIN
  INSERT dbo.table(PK, ...) SELECT @PK, ...;
END
COMMIT TRANSACTION;

Maggiori informazioni su questo UPSERT avvicinati qui:

  • Per favore, smetti di usare questo anti-modello UPSERT

Molte persone suggeriranno in questo modo:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
IF EXISTS (SELECT 1 FROM dbo.table WHERE PK = @PK)
BEGIN
  UPDATE ...
END
ELSE
BEGIN
  INSERT ...
END
COMMIT TRANSACTION;

Ma tutto ciò garantisce che potrebbe essere necessario leggere la tabella due volte per individuare le righe da aggiornare. Nel primo esempio, dovrai individuare le righe una sola volta. (In entrambi i casi, se non vengono trovate righe dalla lettura iniziale, si verifica un inserimento.)

Altri suggeriranno in questo modo:

BEGIN TRY
  INSERT ...
END TRY
BEGIN CATCH
  IF ERROR_NUMBER() = 2627
    UPDATE ...
END CATCH

Tuttavia, questo è problematico se non altro per il fatto che consentire a SQL Server di rilevare le eccezioni che avresti potuto evitare in primo luogo è molto più costoso, tranne nel raro scenario in cui quasi tutti gli inserimenti non riescono. Lo dimostro qui:

  • Verifica di potenziali violazioni dei vincoli prima di accedere a TRY/CATCH
  • Impatto sulle prestazioni delle diverse tecniche di gestione degli errori

Non sono sicuro di cosa pensi di guadagnare avendo una singola affermazione; Non credo che guadagni nulla. MERGE è una singola istruzione ma deve comunque eseguire davvero più operazioni, anche se ti fa pensare che non lo faccia.