Come si gestiscono i vincoli FK durante l'importazione dei dati utilizzando l'importazione / esportazione guidata DTS?


16

Sto cercando di utilizzare l'importazione / esportazione guidata di SQL Server per copiare i dati dal mio db di produzione al mio db di sviluppo, ma quando lo faccio fallisce con l'errore "Lo statuto INSERT è in conflitto con il vincolo FOREIGN KEY" ho oltre 40 tabelle con lotti dei vincoli FK, esiste un modo semplice per gestirlo senza dover scrivere un vincolo di rilascio / aggiungere uno script constrat?

Modifica: ho appena scoperto che nell'edizione Web di SQL Server, che è quello che sto eseguendo, DTS non ti permetterà di salvare i pacchetti.

Risposte:


28

Mi è stata data questa soluzione su SQLTeam.com:

Uso:

 EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

Quindi importa i tuoi dati

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT all'

Usando quel metodo sono stato in grado di importare tutti i dati senza problemi.


1
sp_msforeachtable(e sp_MSForEachDb) non è documentato e non è supportato. Non dovresti / evitare di usarlo. Potrebbe saltare i tavoli !! Vedi questo post da @AaronBertrand -> sqlblog.com/blogs/aaron_bertrand/archive/2010/12/29/… e questo elemento di connessione - (MS indica che non lo ripareranno ) -> connect.microsoft.com/SQLServer / feedback / dettagli / 264677 /…
Kin Shah,

Ha funzionato perfettamente per me dopo ore di battute cerebrali cercando di aggirare i vincoli FK per un'esportazione di dati.
levininja,

In esecuzione su Azure SQL V12, viene visualizzato l'errore "Impossibile trovare la stored procedure 'sp_msforeachtable'."
Dai

Non funziona comunque: /
Douglas Gaskell,

Sei l'uomo che salva la vita
Can Şahin Bakır,

5

Ho prodotto una copia esatta di un database sulla mia macchina da un server che non controllavo.

Sono uno schmuck , ma questo è quello che ho fatto:

  1. Creato il DB dal mio script che era nel controllo del codice sorgente (suggerimento, suggerimento!) Se non si dispone dello script, è sempre possibile generarlo dal DB esistente tramite l' Tasksopzione.

  2. Se durante la creazione sono stati inseriti automaticamente dati in YourDB , eseguire a DELETE FROM YourDB.dbo.tblYourTable.

    • Non è possibile troncare i dati quando esistono chiavi esterne, quindi è necessario utilizzare DELETE.
  3. Esegui questo sul tuo server di destinazione: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all';

  4. Fare clic con il tasto destro su YourDB in Object Explorer. Fai clic su Tasks->Import Data...

  5. Le prime schermate della procedura guidata sono autoesplicative.

  6. Nella Select Source Table and Viewsschermata della procedura guidata, fai clic sulla casella di controllo accanto a ogni tabella che desideri copiare.

  7. Per ogni riga (tabella) su quella schermata, fai clic su di essa in modo che sia evidenziata, quindi fai clic Edit Mappings.

  8. Per ogni riga (tabella), fare clic su / selezionare Append rows to the destination tablee Enable identity insert.

    • Se fai clic Delete rows in destination tablefallirà perché non emette un DELETEcomando, emette un TRUNCATEcomando che è ancora in conflitto con le nostre chiavi esterne perché TRUNCATEnon è governato NOCHECK CONSTRAINTdal precedente.
  9. Fai clic sul resto della procedura guidata e fai clic Finish.

  10. Guarda per errori ; gli avvisi sono probabilmente ok da ignorare.

    • In caso di errori, fare clic sul Reportpulsante e visualizzare il rapporto. Cercare di suss fuori quello che era un Success, Errore Stopped. Probabilmente dovrai correggere qual è stata la causa principale dell'errore che è sepolto in quel rapporto da qualche parte. Quindi, probabilmente dovrai fare un DELETE FROM YourDB.dbo.theErrorTable. Ora fai clic sul pulsante Indietro nella procedura guidata di importazione e deseleziona tutte le tabelle che erano a Success. Ripeti all'infinito.
  11. Esegui questo sul tuo server di destinazione: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all';

    • Se ci sono errori, ... Non lo so, ma correggili e riprova!
  12. Sìì! :)

Grazie a tutti coloro che hanno risposto a questa domanda e a domande simili a questa sulla rete SE per avermi aiutato a capirlo.


Stai salvando la vita
Tom Gullen,

1
Seriamente grazie mille, ho avuto un backup su un disco danneggiato, impossibile copiare il DB ovunque (errore I / O). L'importazione di alcuni dati alla volta in questo modo mi ha aiutato a recuperarne il 99%.
Tom Gullen,

1
Sei forte! Un altro comando che mi ha aiutato: EXEC sp_msforeachtable 'elimina da? '; Se si verifica un errore, eliminare tutto è la legge. Lo script sp_msforeachtable è qui gist.githubusercontent.com/metaskills/893599/raw/…
Sanchitos

4

Nella procedura guidata di importazione, è possibile eliminare prima le righe e se si dispone di campi identità, è possibile abilitare l'inserimento identità come di seguito

inserisci qui la descrizione dell'immagine

Se si desidera disabilitare il vincolo di controllo, quando la procedura guidata richiede di salvare il pacchetto, salvarlo e quindi modificare la gestione connessione come di seguito:

inserisci qui la descrizione dell'immagine

Nota: non è possibile TRUNCARE la tabella quando sono definite chiavi esterne.


3

Non lasciar cadere i vincoli.

Quello che dovresti fare è salvare il pacchetto SSIS creato dalla procedura guidata, quindi modificarlo in BIDS / SSDT. Quando modifichi il pacchetto sarai in grado di controllare l'ordine in cui vengono elaborate le tabelle in modo da poter elaborare le tabelle padre quindi elaborare le tabelle figlio quando tutte le tabelle principali sono state completate.


3
Neanche questo è davvero efficace, ci vorrebbe quasi un'ora adesso per modificare il pacchetto per assicurarsi che tutto sia nell'ordine corretto, e anche allora non posso esserne sicuro. Ciò diventerebbe più ingombrante man mano che il DB cresce e lo fa ogni volta, no grazie. Deve esserci un modo semplice per farlo.

1

Problemi come questo ci mostrano che le persone che creano SQL Server non hanno mai effettivamente utilizzato il loro prodotto. Questa è un'omissione così evidente che ci si deve chiedere cos'altro si sono semplicemente dimenticati di fare correttamente (ho un elenco di circa 30 altri problemi esasperanti come questo che ho dovuto superare per far funzionare questo come fanno altri DB della scatola; incluso il fatto che abbiamo bisogno di un mago pessimo per farlo in primo luogo [se avessi il tempo che ho trascorso ad aspettare che questo mago si connettesse ed enumerasse le stesse tabelle per lo stesso DB, ogni volta, indietro ... avrei tempo per una bella vacanza]).

Sono molto pigro e non voglio scrivere EXEC sp_msforeachtable ...due volte ogni volta che lo faccio. Il mio lavoro è stato quello di lasciare i vincoli sul server di produzione e rimuoverli dal server di sviluppo. Questo impedirà l'errore ma questo metodo ha alcuni effetti collaterali MOLTO GRANDI. Innanzitutto, non sarai più in grado di ripristinare un backup completo sul tuo server di sviluppo (a meno che tu non stia bene rimuovendoli di nuovo). In secondo luogo, funziona meglio quando sei sicuro che anche i consumatori dei tuoi dati applicano questi vincoli (o non se ne curano). Nel mio caso, abbiamo un solo consumatore (il nostro sito Web), quindi abbiamo inserito anche questi vincoli nel codice del sito (ovvero prima di eliminare un record utente eliminiamo prima tutti i record telefonici per quell'utente). Sì, questo essenzialmente nega la necessità di vincoli in primo luogo e raddoppia il lavoro che devo fare, ma mi dà anche la possibilità di verificare che il mio codice funzioni con o senza vincoli basati su DBMS (il fatto è che sono ancora in gioco server solo come piano di emergenza). Potresti definire questo un difetto nel mio progetto, ma preferirei definirlo una soluzione alternativa per un DBMS difettoso. Ad ogni modo, è ancora più veloce e più facile farlo altrove che all'interno di MSSQL perché non è in grado di far fronte al proprio design.


0

Penso che non sia possibile eseguire il backup e il ripristino dal server di produzione in quanto si tratta di dati cruciali. Bene senza i diritti propri diventa davvero più complicato. Ma se hai il db backup n restore giusto allora puoi eseguirlo.

Altrimenti, un modo che consiglierei comunque di eliminare tutti i tuoi vincoli e indici e quindi aggiungerli nuovamente una volta che i dati sono stati importati o esportati.

Non è una risposta esatta ma verrà elaborata rapidamente.


Grazie, ma in particolare ho detto che non voglio scrivere uno script di vincolo drop / create.

0

Basta leggere quell'argomento. È un vecchio post, ma ecco cosa ho fatto per aiutare le persone future a leggere questo.

Nel mio caso volevo importare in una tabella identica vuota. Quando modifico la mappatura, seleziono <ignore>per la chiave primaria. Tutti i miei contenuti vengono aggiunti automaticamente in modo corretto.

Spero che aiuti qualcuno


1
Ignorare la chiave primaria sarebbe di aiuto con le chiavi esterne?
dezso

Nel mio caso sì, dato che stavo effettivamente duplicando una tabella. Quindi ho finito con le stesse chiavi primarie. Quindi le chiavi esterne che puntano al mio tavolo sono ancora corrispondenti alla voce corretta
Greg
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.