2010-04-29 16 views
6

Ho alcune tabelle in cui vengono aggiunti i vincoli di chiave esterna. Questi sono usati con la generazione del codice per impostare specifici join nelle stored procedure generate.SQL Server: eliminazione di righe con vincoli di chiave esterna: le transazioni possono sovrascrivere i vincoli?

È possibile sovrascrivere questi vincoli chiamando più eliminazioni all'interno di una transazione, in particolare "TransactionScope" in C# oppure l'eliminazione a cascata è assolutamente necessaria?

risposta

13

Non utilizzare l'eliminazione a cascata, è possibile causare problemi di prestazioni gravi in ​​questo modo. La procedura migliore consiste nell'eseguire le eliminazioni in ordine dalla tabella figlio inferiore alla tabella padre.

La disabilitazione delle chiavi esterne è una prescrizione per i problemi di integrità dei dati. L'unica volta che una cosa del genere dovrebbe essere fatta da un DBA che è estremamente esperto e ben consapevole dei problemi che potrebbero causare. Se stai facendo questa domanda, non hai ancora esperienza sufficiente per usare quella tecnica. Ricorda quando disabiliti l'FK, lo disabiliti per tutti e non solo per il tuo processo.

+0

OP dice: '... Vengono aggiunti i vincoli di chiave esterna che vengono utilizzati con la generazione del codice per impostare specifici join nelle stored procedure generate. –

+0

@HLGEM : Concordo sul fatto che in questa situazione (descritta in uno dei miei commenti su un'altra risposta) l'eliminazione dell'ordinamento del bambino più basso è probabilmente l'opzione migliore –

+5

Non sono d'accordo sul fatto che le eliminazioni a cascata causino un problema di prestazioni. la soluzione più efficiente possibile (guarda il piano di esecuzione). Se lo fai manualmente devi eseguire la stessa quantità di lavoro ma di più inefficiente. – usr

2

Non è possibile sovrascrivere i vincoli FK, se fosse possibile quale sarebbe il punto di crearli in primo luogo?

+1

true, ciò che intendo è, suppongo: è che il vincolo/i riferimenti di chiave esterna non verrebbero convalidati/controllati sulle righe fino alla fine della transazione, quindi le eliminazioni a cascata non sarebbero necessarie. –

+2

Non ci credo; anche all'interno di una transazione viene applicata l'integrità relazionale. Puoi disabilitare gli FK come fa notare OMG. –

+1

Peccato che l'integrità non sia verificata alla fine di una transazione (o abilitata/configurata per farlo), sarebbe d'aiuto. –

7

L'unico modo per "Override" un foreign key constraint è per disattivarlo:

disabilitazione di un vincolo FOREIGN KEY permette dati nella tabella da modificare senza essere convalidato dai vincoli. Disabilitare un vincolo FOREIGN KEY durante le istruzioni INSERT e UPDATE se i nuovi dati violano il vincolo o se il vincolo deve applicarsi solo ai dati già presenti nel database.

è necessario utilizzare il comando ALTER TABLE per disabilitare un vincolo, utilizzando la parola chiave NOCHECK. IE:

ALTER TABLE dbo.cnst_example NOCHECK CONSTRAINT salary_cap; 

L'unica alternativa è quella di eliminare il vincolo e aggiungere nuovamente quando necessario.

La necessità di fare questo dovrebbe portare a discussioni su come modellare le tabelle, quindi questo non è necessario.

+1

+1, esattamente quello che stavo pensando, se l'FK esiste solo per un'utilità di codice gen per creare alcune stored procedure, quindi lasciarle non sarebbe un problema. –

+0

KM: Facciamo molto del codice gen, di solito eliminiamo i vincoli per i database di produzione e anche raramente cancelliamo qualsiasi record. Quindi i vincoli di solito non sono un problema. Nel nuovo modello Multi-Tenancy pensavamo di tenerli dentro, ma eliminare un intero inquilino, che è richiesto, ci dà questo problema di chiave estera. Preferirei non disabilitare/abilitare o eliminare/creare i vincoli. Immagino che potremmo ridurre l'ordine delle cancellazioni (che sembrano una scelta ovvia, o non possiamo semplicemente usare i vincoli come menzionate. –

+0

@ Mark Redman: l'integrità dei dati è altamente discutibile se non ci sono vincoli in atto –

1

Se i vincoli FK sono espressamente indicate per l'uso specifico nelle stored procedure, queste non sono davvero FK di, non è vero? una buona soluzione sarebbe quella di aggiornare il codice corrispondente creando i vincoli all'inizio del processo e cancellandoli quando il codice è terminato. Non dimenticare poi di trattare il caso in cui il tuo vincolo temporaneo non può essere verificato rispetto ai dati.

+0

Sono usati per impostare alcuni join nella generazione del codice (seleziona ecc.), Ma funzionano come se gli FK fossero lasciati. –

1

I vincoli possono essere impostati su immediato o ritardato fino alla fine di una transazione. Ritardare alla fine di una transazione consente di violare i vincoli mentre si sta costruendo la transazione, ma applicarli alla fine della transazione. Da quello che ho capito, il ritardo alla fine di una transazione è ciò che probabilmente stai cercando.

Problemi correlati