none
Insert senza controllo violazione di chiave RRS feed

  • 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

    mercoledì 10 luglio 2013 17:22

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


    lunedì 15 luglio 2013 15:33
    Moderatore

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

    giovedì 11 luglio 2013 09:07
  • Grazie per la risposta,

    non ho bisogno di alternative, so come. Avrei solo bisogno di una risposta secca alla domanda.

    Non è necessario il log.

    Grazie ancora.

    Saluti.

    domenica 14 luglio 2013 07:25
  • 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


    domenica 14 luglio 2013 09:33
  • 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


    lunedì 15 luglio 2013 15:33
    Moderatore
  • 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

    mercoledì 17 luglio 2013 14:56