web-dev-qa-db-fra.com

Comment gérer les contraintes FK lors de l'importation de données à l'aide de DTS Assistant d'importation / exportation?

J'essaie d'utiliser l'importation et l'exportation SQL Server Wizard pour copier les données de ma base de données de production vers ma base de données de développement, mais lorsque je le fais, cela échoue avec l'erreur "L'instruction INSERT est en conflit avec la CLÉ ÉTRANGÈRE "J'ai plus de 40 tables avec beaucoup de contraintes FK, existe-t-il un moyen facile de gérer cela sans avoir à écrire un script de contrainte de suppression/ajout de constrat?

Edit: Je viens de découvrir que dans l'édition Web de SQL Server, qui est ce que j'exécute, DTS ne vous permettra pas d'enregistrer des packages.

16
user11512

On m'a donné cette solution sur SQLTeam.com:

Utilisation:

 EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all'

Importez ensuite vos données

EXEC sp_msforeachtable 'ALTER TABLE ? CHECK CONSTRAINT all'

En utilisant cette méthode, j'ai pu importer toutes les données sans aucun problème.

30
user11512

J'ai produit une copie exacte d'une base de données sur ma machine à partir d'un serveur que je ne contrôlais pas.

je suis un schmuck, mais c'est ce que j'ai fait:

  1. Création de la base de données à partir de mon script qui était sous contrôle de code source (indice, indice!) Si vous n'avez pas le script, vous pouvez toujours le générer à partir de la base de données existante via l'option Tasks.

  2. Si des données ont été insérées automatiquement dans YourDB lors de la création, exécutez un DELETE FROM YourDB.dbo.tblYourTable.

    • Vous ne pouvez pas tronquer les données lorsque des clés étrangères existent, vous devez donc utiliser DELETE.
  3. Exécutez ceci sur votre serveur de destination: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT all';

  4. Faites un clic droit sur YourDB dans Object Explorer. Cliquez sur Tasks -> Import Data...

  5. Les premiers écrans de l'assistant sont explicites.

  6. Sur le Select Source Table and Views écran de l'assistant, cochez la case en regard de chaque table que vous souhaitez copier.

  7. Pour chaque ligne (tableau) de cet écran, cliquez dessus pour la mettre en surbrillance, puis cliquez sur Edit Mappings.

  8. Pour chaque ligne (tableau), cliquez/cochez Append rows to the destination table et Enable identity insert.

    • Si vous cliquez sur Delete rows in destination table il échouera car il n'exécute pas de commande DELETE, il émet une commande TRUNCATE qui entre toujours en conflit avec nos clés étrangères car TRUNCATE n'est pas régi par le NOCHECK CONSTRAINT du précédent.
  9. Cliquez sur le reste de l'assistant et cliquez sur Finish.

  10. Surveillez les erreurs ; les avertissements peuvent probablement être ignorés.

    • S'il y a des erreurs, cliquez sur le bouton Report et affichez le rapport. Essayez de déterminer ce qu'était un Success, Error et Stopped. Vous devrez probablement corriger la cause première de l'erreur qui est enfouie quelque part dans ce rapport. Ensuite, vous devrez probablement faire un DELETE FROM YourDB.dbo.theErrorTable. Cliquez maintenant sur le bouton de retour de l'assistant d'importation et décochez chaque table qui était un Success. Répétez à l'infini.
  11. Exécutez ceci sur votre serveur de destination: USE YourDB; EXEC sp_msforeachtable 'ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all';

    • S'il y a des erreurs, ... je ne sais pas, mais corrigez-les et réessayez!
  12. Yay! :)

Merci à tous ceux qui ont répondu à cette question et aux questions similaires à celle-ci sur le réseau SE de m'avoir aidé à comprendre cela.

5
Zach Mierzejewski

Dans l'assistant d'importation, vous pouvez d'abord supprimer les lignes et si vous avez des champs d'identité, vous pouvez ensuite activer l'insertion d'identité comme ci-dessous

enter image description here

Si vous souhaitez désactiver la contrainte de vérification, lorsque l'assistant vous demande d'enregistrer le package, enregistrez-le, puis modifiez le gestionnaire de connexions comme ci-dessous:

enter image description here

Remarque: vous ne pouvez pas TRONCER la table lorsque des clés étrangères sont définies.

4
Kin Shah

Ne laissez pas tomber les contraintes.

Ce que vous devez faire est d'enregistrer le package SSIS créé par l'assistant, puis de le modifier dans BIDS/SSDT. Lorsque vous modifiez le package, vous pourrez contrôler l'ordre dans lequel les tables sont traitées afin que vous puissiez traiter les tables parentes puis traiter les tables enfants lorsque toutes les tables parentes sont terminées.

3
mrdenny

Des problèmes comme celui-ci nous montrent que les personnes qui créent SQL Server n'ont jamais réellement utilisé leur produit. C'est une omission tellement flagrante qu'il faut se demander ce qu'ils ont simplement oublié de faire correctement (j'ai une liste d'environ 30 autres problèmes exaspérants comme celui-ci que j'ai dû surmonter pour que cela fonctionne comme d'autres DB le font de la boîte; y compris le fait que nous avons besoin d'un assistant moche pour le faire en premier lieu [si j'avais le temps que j'ai passé à attendre que cet assistant se connecte et énumère les mêmes tables pour la même base de données, à chaque fois, retour ... j'aurais le temps pour de belles vacances]).

Je suis très paresseux et je ne veux pas taper EXEC sp_msforeachtable ... deux fois à chaque fois que je fais cela. Mon travail a consisté à laisser les contraintes sur le serveur de production et à les supprimer du serveur de développement. Cela empêchera l'erreur mais cette méthode a quelques TRÈS GRANDS effets secondaires. Tout d'abord, vous ne pourrez plus simplement restaurer une sauvegarde complète sur votre serveur de développement (sauf si vous êtes d'accord pour les supprimer à nouveau). Deuxièmement, cela fonctionne mieux lorsque vous êtes sûr que les consommateurs de vos données appliquent également ces contraintes (ou ne s'en soucient pas). Dans mon cas, nous n'avons qu'un seul consommateur (notre site Web), nous avons donc également intégré ces contraintes dans le code du site (c'est-à-dire avant de supprimer un enregistrement d'utilisateur, nous supprimons d'abord tous les enregistrements téléphoniques de cet utilisateur). Oui, cela annule essentiellement le besoin de contraintes et double le travail que je dois faire, mais cela me donne également la possibilité de vérifier que mon code fonctionne avec ou sans contraintes basées sur SGBD (le fait est qu'elles sont toujours activées). le serveur Prod uniquement comme plan d'urgence). Vous pouvez appeler cela une faille dans ma conception, mais je préfère appeler cela une solution de contournement pour un SGBD défectueux. Quoi qu'il en soit, il est toujours plus rapide et plus facile de le faire ailleurs que dans MSSQL car il est incapable de faire face à sa propre conception.

1
krowe2

Lisez simplement ce sujet. C'est un vieux post mais voici ce que j'ai fait pour aider les futures personnes à lire ceci.

Dans mon cas, je voulais importer dans une table identique vide. Lors de la modification du mappage, je sélectionne <ignore> pour la clé primaire. Tout mon contenu est bien ajouté automatiquement.

J'espère que cela aide quelqu'un

0
Greg

Je pense que vous ne pouvez pas effectuer de sauvegarde et de restauration à partir du serveur de production car il s'agit d'une donnée cruciale. Eh bien, sans les droits appropriés, cela devient vraiment plus compliqué. Mais si vous avez droit à la sauvegarde et à la restauration de la base de données, vous pouvez l'exécuter.

Ou bien, une façon que je recommanderais est de supprimer toutes vos contraintes et index, puis de les ajouter à nouveau une fois les données importées ou exportées.

Pas une réponse exacte, mais elle sera traitée rapidement.

0
user2404431