sto affrontando il seguente problema:Come evitare eccezioni chiave duplicate in modo efficiente
Sto cercando di mantenere una tabella in SQL-Server sincronizzato con più database esterni. Questi database esterni non hanno una chiave primaria univoca condivisa, quindi la tabella locale ha un PK intero semplice.
Ora per mantenere la tabella locale fino ad oggi la seguente è fatto:
- banche dati esterne vengono interrogati.
- I dati vengono convertiti in dati validi per la tabella locale.
- Un inserto viene utilizzato per provare a scrivere i dati nella tabella locale.
- Se insert restituisce un'eccezione di immissione duplicata, il PK verrà ricercato da una query di selezione ei dati verranno scritti nella tabella da una query di aggiornamento.
- Un'altra tabella viene modificata utilizzando il PK della riga inserita o aggiornata.
Ora questo funziona bene ma a me sembra molto inefficiente. La maggior parte delle volte i dati sono già nella tabella locale e generano un'eccezione chiave duplicata sull'inserto. Ciò significa che molte eccezioni devono essere gestite, il che è costoso. Inoltre, poiché i PK sono gestiti dal DB, è necessario utilizzare una query di selezione per trovare la riga da aggiornare.
Come posso evitare questo effetto? Non voglio utilizzare una stored procedure come mi piace per mantenere la query gestibile dal codice e inclusa nel controllo della versione.
Ho visto l'unione ma ho visto troppe persone che hanno segnalato problemi con esso.
Penso di aver bisogno di usare un modulo di upsert ma non sono sicuro di come farlo con il PK gestito dal DB.
tl; dr: Ciò di cui ho bisogno è una query che mi consenta di inserire o aggiornare una riga (a seconda della chiave duplicata o meno) che restituirà sempre il PK della riga.
L'istruzione MERGE è il comando upsert per SQL Server –
@SteveFord Lo so, ma ci sono segnalazioni di rallentamenti e/o errori. Non è più così? Vedere: http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/ http://www.sqlservercentral.com/Forums/Topic1465931-391-1.aspx –
abbastanza corretto @ mike-van-leeuwen un approccio alternativo sarebbe quello di eseguire prima l'UPDATE usando un'istruzione OUTPUT per catturare le righe aggiornate in una tabella temporanea. Quindi esegui un INSERT ... SELECT .... WHERE NOT EXISTS (SELECT * FROM temptable) –