Principale utente con più risposte
Insert senza controllo violazione di chiave

Domanda
-
Salve a tutti,
pongo una domanda: è possibile in SQLServer impostare una INSERT in modo tale che inserisca tutte le righe desiderate e tralasci automaticamente quelle con violazione di chiave? Ossia devo fare una INSERT dalla tabella A alla tabella B; la tabella B possiede un campo chiave; vorrei fare una insert secca da A verso B che deve aggiungere tutte le righe che può (e cioè quelle che non danno violazione di chiave) senza che ritorni il classico errore di violazione. Le righe che violano la chiave deve semplicemente tralasciarle.
Grazie per l'attenzione.
Luigi
Risposte
-
Ciao,
che ne dici di usare la merge? In questo modo puoi evitare le violazioni di chiave disegnando opportunamente la chiave di match: MERGE STATEMENT.
In alternativa potresti agire su IGNORE_DUP_KEY (opzione dell'indice, in questo caso immagino la PK):
Direttamente dalla documentazione:
"IGNORE_DUP_KEY = { ON | OFF }
Specifica l'errore restituito quando un'operazione di inserimento tenta di inserire valori di chiave duplicati in un indice univoco. L'opzione IGNORE_DUP_KEY viene applicata solo alle operazioni di inserimento eseguite dopo la creazione o la ricompilazione dell'indice.CREATE INDEX, ALTER INDEX o UPDATE. Il valore predefinito è OFF.
- ON
-
Viene visualizzato un messaggio di avviso quando i valori di chiave duplicati vengono inseriti in un indice univoco. Avranno esito negativo solo le righe che violano il vincolo di unicità.
- OFF
-
Viene visualizzato un messaggio di errore quando i valori di chiave duplicati vengono inseriti in un indice univoco. Viene eseguito il rollback dell'intera operazione INSERT.
L'opzione IGNORE_DUP_KEY non può essere impostata su ON per gli indici creati in una vista, gli indici non univoci, gli indici XML, spaziali e filtrati."
Ma non mi piace molto suggerirla come soluzione. Una buona MERGE ti permette di considerare i casi di violazione evitandoli a priori.
Alessandro Alpi SQL Server MVP
- Modificato Alessandro AlpiMVP, Moderator lunedì 15 luglio 2013 15:35 copia incolla errato
- Contrassegnato come risposta Fabrizio-GMVP, Moderator venerdì 26 luglio 2013 08:15
Tutte le risposte
-
Prima di proporti qualsiasi soluzione ho bisogno di sapere una cosa...
Perchè?
Scusa, senza offesa, ma sono curioso di sapere che tipo di applicazione possa avere un esigenza come quella da te descritta. I dati "scartati", devono comunque essere salvati in un log di errori?
Luca Dalsass
Solution Architect and Development Manager presso Totalcom Srl Bolzano- blog : Diario di un programmatore
- blog : Videogioco troppo poco
-
-
La soluzione più veloce che mi viene in mente è ciclare sui record che intendi inserire e effettuare ogni insert in un blocco try {} catch {}.
Se lo esegui da codice è molto semplice. Ma volendo lo puoi fare anche in una stored direttamente in sql server.
Il cicli in SQL server si chiamano cursori : msdn
i blocchi try catch esistono anche in sql server : msdn
Luca Dalsass
Solution Architect and Development Manager presso Totalcom Srl Bolzano- blog : Diario di un programmatore
- blog : Videogioco troppo poco
- Modificato shjonblake domenica 14 luglio 2013 09:34 aggiunte
- Proposto come risposta Irina Turcu lunedì 15 luglio 2013 12:40
- Contrassegnato come risposta Fabrizio-GMVP, Moderator venerdì 26 luglio 2013 08:14
- Contrassegno come risposta annullato Fabrizio-GMVP, Moderator venerdì 26 luglio 2013 08:15
- Proposta come risposta annullata Fabrizio-GMVP, Moderator venerdì 26 luglio 2013 08:15
-
Ciao,
che ne dici di usare la merge? In questo modo puoi evitare le violazioni di chiave disegnando opportunamente la chiave di match: MERGE STATEMENT.
In alternativa potresti agire su IGNORE_DUP_KEY (opzione dell'indice, in questo caso immagino la PK):
Direttamente dalla documentazione:
"IGNORE_DUP_KEY = { ON | OFF }
Specifica l'errore restituito quando un'operazione di inserimento tenta di inserire valori di chiave duplicati in un indice univoco. L'opzione IGNORE_DUP_KEY viene applicata solo alle operazioni di inserimento eseguite dopo la creazione o la ricompilazione dell'indice.CREATE INDEX, ALTER INDEX o UPDATE. Il valore predefinito è OFF.
- ON
-
Viene visualizzato un messaggio di avviso quando i valori di chiave duplicati vengono inseriti in un indice univoco. Avranno esito negativo solo le righe che violano il vincolo di unicità.
- OFF
-
Viene visualizzato un messaggio di errore quando i valori di chiave duplicati vengono inseriti in un indice univoco. Viene eseguito il rollback dell'intera operazione INSERT.
L'opzione IGNORE_DUP_KEY non può essere impostata su ON per gli indici creati in una vista, gli indici non univoci, gli indici XML, spaziali e filtrati."
Ma non mi piace molto suggerirla come soluzione. Una buona MERGE ti permette di considerare i casi di violazione evitandoli a priori.
Alessandro Alpi SQL Server MVP
- Modificato Alessandro AlpiMVP, Moderator lunedì 15 luglio 2013 15:35 copia incolla errato
- Contrassegnato come risposta Fabrizio-GMVP, Moderator venerdì 26 luglio 2013 08:15
-
Leggendo la risposta di Alessandro mi sono accorto che forse ho male interpretato la domanda.
Non so perché, ma ero convinto che le chiavi in questione fossero delle "Foreign key". Invece stiamo parlando della chiave primaria della tabella.
In questo caso appoggio la risposta di Alessandro.
L'istruzione "MERGE" purtroppo funziona solo sa SQL Server 2008 in poi.
Dovesse essere il tuo un database 2005 o inferiore puoi sempre usare una INSERT ed inserire la join delle tabelle A e B, dove tieni conto solo dei valori che non sono presenti in B.
Esempio:
INSERT INTO B (CAMPO_1, CAMPO_2, ecc) SELECT A.CAMPO_1, A.CAMPO_2, ecc FROM A LEFT JOIN B ON A.CHIAVE = B.CHIAVE WHERE B.CHIAVE IS NULL
Luca Dalsass
Solution Architect and Development Manager presso Totalcom Srl Bolzano- blog : Diario di un programmatore
- blog : Videogioco troppo poco