SqlBulkCopy Gestion des erreurs / poursuite après erreur

ado.net c# sqlbulkcopy

Question

J'essaie d'insérer une énorme quantité de données dans le serveur SQL. Ma table de destination a un index unique appelé "Hash".

Je voudrais remplacer mon implémentation SqlDataAdapter par SqlBulkCopy. SqlDataAapter contient une propriété appelée "ContinueUpdateOnError", lorsqu'elle est définie sur true, adapter.Update (table) insère toutes les lignes possibles et marque les lignes d'erreur avec la propriété RowError.

La question est de savoir comment puis-je utiliser SqlBulkCopy pour insérer des données aussi rapidement que possible tout en gardant une trace des lignes insérées et des autres (en raison de l'index unique)?

Voici les informations supplémentaires:

  1. Le processus est itératif, souvent défini selon un calendrier à répéter.

  2. Les tables source et destination peuvent être énormes, parfois des millions de lignes.

  3. Même s'il est possible de vérifier d'abord les valeurs de hachage, deux transactions par ligne sont nécessaires (d'abord pour sélectionner le hachage dans la table de destination, puis effectuer l'insertion). Je pense que dans le cas de adapter.update (table), il est plus rapide de rechercher la valeur RowError que de rechercher les résultats de hachage par ligne.

Réponse acceptée

SqlBulkCopy, dispose de fonctionnalités de traitement des erreurs très limitées. Par défaut, il ne vérifie même pas les contraintes.

Cependant, c'est rapide, vraiment très rapide.

Si vous souhaitez contourner le problème de clé en double et identifier les lignes en double d'un lot. Une option est:

  • commencer tran
  • Prenez un tablockx sur la table, sélectionnez toutes les valeurs actuelles du "hachage" et jetez-les dans un hachage.
  • Filtrez les doublons et créez un rapport.
  • Insérer les données
  • commettre tran

Ce processus fonctionnera efficacement si vous insérez des ensembles énormes et si la taille des données initiales dans le tableau n'est pas trop énorme.

Pouvez-vous développer votre question pour inclure le reste du contexte du problème?

MODIFIER

Maintenant que j'ai un peu plus de contexte, voici une autre façon de procéder:

  • Faites l'insertion en vrac dans une table temporaire.
  • commencer un tran sérialisable
  • Sélectionnez toutes les lignes temporaires qui sont déjà dans la table de destination ... faites un rapport dessus
  • Insérez les données de la table temporaire dans la table réelle, en effectuant une jointure gauche sur un hachage et en incluant toutes les nouvelles lignes.
  • commettre le tran

Ce processus est très léger lors des allers-retours et, compte tenu de vos spécifications, il devrait être très rapide.


Réponse populaire

Approche légèrement différente de celle déjà suggérée; Effectuez la SqlBulkCopy et attrapez la levée SqlException :

    Violation of PRIMARY KEY constraint 'PK_MyPK'. Cannot insert duplicate 
key in object 'dbo.MyTable'. **The duplicate key value is (17)**.

Vous pouvez ensuite supprimer tous les éléments de votre source de l'ID 17, le premier enregistrement dupliqué. Je fais des hypothèses qui s’appliquent à ma situation et éventuellement pas à la vôtre; c'est-à-dire que la duplication est provoquée par les mêmes données exactes d'un SqlBulkCopy précédemment défaillant en raison d'erreurs SQL / réseau lors du téléchargement.



Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi